R 데이터 다루기 고급 스킬 완전 정복: enframe부터 join 개선까지

enframe/deframe/reframe, purrr::transpose, expand·crossing, seq 계열, 누적 계산, 중복/고유, nest/unnest, join 개선, case_when/if_else까지 한 번에 정리한 고급 실습 가이드.
데이터·통계
저자

Ikmyungterran

공개

2026년 2월 1일

Modified

2026년 3월 8일

0. 이 글의 목표

이 글은 R 데이터 다루기 고급 스킬을 체계적으로 정리하여 설명합니다. 각 함수마다 1) 무엇을 하는지, 2) 언제 쓰는지, 3) 인수(파라미터) 의미, 4) 코드 + 결과 예시를 순서대로 설명합니다.

R 데이터 고급 조작 개요 이미지

사용 패키지

library(tidyverse)

1. enframe() / deframe(): 벡터 ↔︎ 데이터프레임 전환

1.1 enframe(): 벡터를 데이터프레임으로

무엇을? - 이름이 있는 벡터(named vector)를 name / value 2열 티블로 바꿉니다.

언제 쓰나? - 결과를 데이터프레임 형태로 다뤄야 할 때 - 벡터를 dplyr 파이프라인에 연결해야 할 때

주요 인수 - x: 변환할 벡터 - name: 이름 열의 이름(기본: name) - value: 값 열의 이름(기본: value)

v <- c(a = 10, b = 20, c = 30)

enframe(v, name = "key", value = "val")

예시 출력:

# A tibble: 3 × 2
  key    val
  <chr> <dbl>
1 a        10
2 b        20
3 c        30

1.2 deframe(): 데이터프레임을 벡터로

무엇을? - name / value 형태의 2열 티블을 named vector로 되돌립니다.

언제 쓰나? - 데이터프레임을 벡터로 바꿔서 빠르게 조회하고 싶을 때 - 벡터 기반 함수(예: setNames, match)와 함께 쓸 때

주요 인수 - x: 2열 티블 (첫 열=이름, 둘째 열=값)

df <- tibble(name = c("a", "b", "c"), value = c(10, 20, 30))

deframe(df)

예시 출력:

 a  b  c 
10 20 30 

2. reframe(): 요약 결과를 여러 행으로 반환

무엇을? - summarise()는 그룹당 1행만 반환하지만, reframe()여러 행 반환 가능합니다.

언제 쓰나? - 그룹별로 상위 N개, 또는 여러 요약행이 필요할 때

주요 인수 - ...: 계산할 요약식

df <- tibble(group = c("A","A","B","B"), x = c(1,2,3,4))

reframe(df,
  max_x = max(x),
  min_x = min(x)
)

예시 출력:

# A tibble: 1 × 2
  max_x min_x
  <dbl> <dbl>
1     4     1

3. purrr::transpose(): 리스트 구조 전환

무엇을? - 리스트의 구조를 행 ↔︎ 열 관점으로 바꿉니다.

언제 쓰나? - API 응답처럼 “행마다 리스트” 형태를 “열마다 리스트”로 바꿔야 할 때

주요 인수 - .l: 리스트

lst <- list(
  list(a = 1, b = 2),
  list(a = 10, b = 20)
)

purrr::transpose(lst)

예시 출력:

$a
$a[[1]]
[1] 1

$a[[2]]
[1] 10

$b
$b[[1]]
[1] 2

$b[[2]]
[1] 20

4. expand / crossing / expand_grid: 조합 만들기

4.1 expand_grid(): 모든 조합 생성

무엇을? - 입력 벡터들의 데카르트 곱(모든 조합) 생성

언제 쓰나? - 실험 설계, 가격/색상/사이즈 조합 생성

expand_grid(
  size = c("S","M"),
  color = c("red","blue")
)

예시 출력:

# A tibble: 4 × 2
  size  color
  <chr> <chr>
1 S     red
2 S     blue
3 M     red
4 M     blue

4.2 crossing(): 중복 제거 후 조합

무엇을? - 입력 벡터에서 중복을 제거한 뒤 모든 조합 생성

crossing(x = c(1,1,2), y = c("A","B"))

예시 출력:

# A tibble: 4 × 2
      x y
  <dbl> <chr>
1     1 A
2     1 B
3     2 A
4     2 B

5. seq(), seq_along(), seq_len(): 순서형 벡터 생성

5.1 seq()

언제 쓰나? - 일정 간격 숫자 만들기

seq(1, 10, by = 2)

예시 출력:

[1] 1 3 5 7 9

5.2 seq_along()

언제 쓰나? - 벡터 길이만큼 인덱스 생성

x <- c("a","b","c")
seq_along(x)

예시 출력:

[1] 1 2 3

5.3 seq_len()

언제 쓰나? - 정확히 N개 길이의 시퀀스 생성

seq_len(5)

예시 출력:

[1] 1 2 3 4 5

6. 연속된 날짜 만들기

언제 쓰나? - 날짜 범위 생성 (타임라인, 캘린더)

seq.Date(from = as.Date("2026-01-01"), to = as.Date("2026-01-07"), by = "day")

예시 출력:

[1] "2026-01-01" "2026-01-02" "2026-01-03" "2026-01-04" "2026-01-05" "2026-01-06" "2026-01-07"

7. set_names(): 이름 지정

언제 쓰나? - 벡터/리스트에 이름을 붙여 가독성 높일 때

x <- c(10, 20, 30)
set_names(x, c("A","B","C"))

예시 출력:

 A  B  C 
10 20 30 

8. 누적 계산: cumsum()과 accumulate()

8.1 cumsum(): 단순 누적합

cumsum(c(1, 2, 3, 4))

예시 출력:

[1] 1 3 6 10

8.2 accumulate(): 사용자 정의 누적

purrr::accumulate(c(1, 2, 3, 4), ~ .x + .y)

예시 출력:

[1] 1 3 6 10

9. 고유값과 중복 제거

9.1 unique()

unique(c(1,1,2,2,3))

예시 출력:

[1] 1 2 3

9.2 duplicated()

duplicated(c(1,1,2,2,3))

예시 출력:

[1] FALSE  TRUE FALSE  TRUE FALSE

9.3 distinct()

iris %>% distinct(Species)

예시 출력:

# A tibble: 3 × 1
  Species
  <fct>
1 setosa
2 versicolor
3 virginica

9.4 n_distinct()

n_distinct(iris$Species)

예시 출력:

[1] 3

10. nest / unnest: 중첩 데이터 다루기

nest/unnest 개념 이미지

10.1 nest()

nested <- iris %>%
  group_by(Species) %>%
  nest()

nested

예시 출력:

# A tibble: 3 × 2
  Species data
  <fct>   <list>
1 setosa  <tibble [50 × 4]>
2 versicolor <tibble [50 × 4]>
3 virginica  <tibble [50 × 4]>

10.2 unnest()

nested %>% unnest(data)

예시 출력(일부):

# A tibble: 150 × 5
  Species Sepal.Length Sepal.Width Petal.Length Petal.Width
  <fct>          <dbl>       <dbl>        <dbl>       <dbl>
1 setosa           5.1         3.5          1.4         0.2

11. unnest_longer / unnest_wider

unnest_longer/unnest_wider 개념 이미지

11.1 unnest_longer()

df <- tibble(id = 1:2, values = list(c(10,20), c(30,40,50)))

df %>% unnest_longer(values)

예시 출력:

# A tibble: 5 × 2
     id values
  <int>  <dbl>
1     1     10
2     1     20
3     2     30
4     2     40
5     2     50

11.2 unnest_wider()

df2 <- tibble(id = 1:2, info = list(list(a=1,b=2), list(a=10,b=20)))

df2 %>% unnest_wider(info)

예시 출력:

# A tibble: 2 × 3
     id     a     b
  <int> <dbl> <dbl>
1     1     1     2
2     2    10    20

12. match.call(): 함수 호출 구조 확인

match.call()함수가 호출될 때 실제 전달된 인수를 확인할 때 사용합니다.

f <- function(x, y = 10) {
  match.call()
}

f(3)

예시 출력:

f(x = 3)

13. 행에서 최대 위치 찾기 (max.col, which.max)

13.1 which.max()

which.max(c(10, 50, 20))

예시 출력:

[1] 2

13.2 max.col()

m <- matrix(c(1,5,3, 4,2,6), nrow = 2, byrow = TRUE)
max.col(m)

예시 출력:

[1] 2 3

14. join 개선 및 확장 (_join 계열)

14.1 기본 left_join()

a <- tibble(id = 1:3, name = c("A","B","C"))
b <- tibble(id = c(1,2), score = c(90, 95))

left_join(a, b, by = "id")

예시 출력:

# A tibble: 3 × 3
     id name  score
  <int> <chr> <dbl>
1     1 A        90
2     2 B        95
3     3 C        NA

14.2 여러 키 조합 join

a <- tibble(id = c(1,1,2), date = as.Date(c("2026-01-01","2026-01-02","2026-01-01")), val = c(10,20,30))
b <- tibble(id = c(1,2), date = as.Date(c("2026-01-01","2026-01-01")), score = c(100, 200))

left_join(a, b, by = c("id","date"))

15. case_when() vs if_else()

15.1 if_else(): 단일 조건

x <- c(1,2,3,4)
if_else(x > 2, "high", "low")

예시 출력:

[1] "low"  "low"  "high" "high"

15.2 case_when(): 여러 조건

x <- c(1,2,3,4)
case_when(
  x <= 1 ~ "very low",
  x <= 3 ~ "medium",
  TRUE   ~ "high"
)

예시 출력:

[1] "very low" "medium"  "medium"  "high"  


공식 문서 및 참고 링크

아래 문서는 이 글에서 다룬 함수들의 원문 정의와 인수 설명을 확인할 때 가장 유용합니다. 실무에서 헷갈리는 부분이 생기면 블로그 예시와 함께 공식 문서를 교차해서 보는 방식이 가장 안전합니다.

함께 읽으면 좋은 글