tibble
을 사용해서 데이터를 구성하면, 수많은 tidyverse
의 패키지들을 이용해서 데이터를 정리하거나 원하는 형태로 가공하기 편하다. 그 중에서 하나의 문자열을 특정 구분자나 규칙(정규식)을 이용하여 여러개의 컬럼으로 나누는 방법을 설명하려 한다.
구분자가 있는 데이터인 경우
구분자가 있는 문자열의 샘플 데이터를 만들어 본다. 아래 t1
데이터는 _
로 데이터가 구분되어 있다. tibble
함수를 사용해서, x
에는 알파벳, y
에는 숫자를 랜덤하게 셋팅해서 unite
함수로 문자열을 하나로 합쳤다.
library(tidyverse)
set.seed(129409238)
t1 = tibble(x = sample(LETTERS, 5),
y = sample(0:9, 5)) %>%
unite("data", x:y, sep = "_")
# A tibble: 5 × 1
data
<chr>
1 N_3
2 F_8
3 L_9
4 O_6
5 H_4
구분자가 명확히 있는 경우, separate
함수를 사용하면 편하게 나눌 수 있다.
t1 %>%
separate(data, into=c('letter', 'number'),
sep = '_', remove = F)
# A tibble: 5 × 3
data letter number
<chr> <chr> <chr>
1 N_3 N 3
2 F_8 F 8
3 L_9 L 9
4 O_6 O 6
5 H_4 H 4
구분자가 없는 데이터의 경우
구분자가 없는 데이터를 샘플로 만들어 본다. 알파벳 한자리에 숫자 한자리를 조립한 형태이다.
set.seed(27840)
t2 = tibble(x = sample(LETTERS, 5),
y = sample(0:9, 5)) %>%
unite("data", x:y, sep = "")
# A tibble: 5 × 1
data
<chr>
1 F6
2 A7
3 U1
4 P8
5 Y9
자리수 규칙이 명확하다면 문자열 위치로 각각 잘라서 컬럼을 추가하는 방법이 제일 간단하다. str_sub
함수를 사용한다.
t2 %>%
mutate(letter = str_sub(data, 1, 1)) %>%
mutate(number = str_sub(data, 2, 2))
# A tibble: 5 × 3
data letter number
<chr> <chr> <chr>
1 F6 F 6
2 A7 A 7
3 U1 U 1
4 P8 P 8
5 Y9 Y 9
문자열 위치만으로는 판단할 수 없다면, 정규식을 이용해서 처리해야 한다. 정규식관련문서는 구글링하면 많이 나오는데, R 패키지중에 stringr
에서 제공하는 cheatsheets 를 참고하면 좋다.
extract
함수의 특징은 into
로 컬럼을 나눌 갯수가 정해지면, regex
에서는 그 갯수만큼 ()
안에 정규식을 각각 만들어 넣어야 한다. 그래서 아래와 같이 정규식을 각각 넣으면 하나의 문자열씩 분리되는 것을 볼 수 있다.
t2 %>%
extract(data, into = c('letter', 'number'),
regex = '(.)(.)', remove = F)
t2 %>%
extract(data, into = c('letter', 'number'),
regex = '(\\w)(\\w)', remove = F)
# 둘 다 같은 결과
# A tibble: 5 × 3
data letter number
<chr> <chr> <chr>
1 F6 F 6
2 A7 A 7
3 U1 U 1
4 P8 P 8
5 Y9 Y 9
[:digit:]
, [:alpha:]
같은 정규식스타일도 가능하다.
t2 %>%
extract(data, into = c('letter', 'number'),
regex = '([[:alpha:]])([[:digit:]])', remove = F)
# A tibble: 5 × 3
data letter number
<chr> <chr> <chr>
1 F6 F 6
2 A7 A 7
3 U1 U 1
4 P8 P 8
5 Y9 Y 9
조건이 불일치하게 되면, 아래와 같이 NA
만 출력되니 유의한다.
t2 %>%
extract(data, into = c('letter', 'number'),
regex = '([[:digit:]])([[:alpha:]])', remove = F)
# A tibble: 5 × 3
data letter number
<chr> <chr> <chr>
1 F6 NA NA
2 A7 NA NA
3 U1 NA NA
4 P8 NA NA
5 Y9 NA NA