데이터를 다루다보면 두 개 이상의 데이터를 서로 합치거나 분리해야 하는 일이 흔하게 발생합니다. 이 가운데 서로 교집합, 합집합, 차집합을 구할 일이 생길 수 있습니다. R의 기본 명령어에 합집함, 교집합, 차집합을 구하는 함수는 union(x, y), intersect(x, y), setdiff(x, y)입니다. 여기에 두 값이 같은지 확인하는 setequal(x, y) 까지 한 묶음으로 볼 수 있습니다. 아래는 간단한 예제입니다.
(x <- 9="" c="" na="" sample="" sort="" span="">->
(y <- 7="" c="" na="" sample="" sort="" span="">->
union(x, y)
intersect(x, y)
setdiff(x, y)
setdiff(y, x)
setequal(x, y)
> (x <- 9="" c="" na="" sample="" sort="" span="">->
[1] 1 5 6 7 8 13 15 16 19 NA
> (y <- 7="" c="" na="" sample="" sort="" span="">->
[1] 3 4 11 13 15 22 23 NA
> union(x, y)
[1] 1 5 6 7 8 13 15 16 19 NA 3 4 11 22 23
> intersect(x, y)
[1] 13 15 NA
> setdiff(x, y)
[1] 1 5 6 7 8 16 19
> setdiff(y, x)
[1] 3 4 11 22 23
> setequal(x, y)
[1] FALSE
다시 앞서 다이아몬드의 예제에서 10개 정도 샘플을 추출한 후 사용법을 알아보겠습니다.
set.seed(3311)
diamonds1<-sample 10="" diamonds="" nrow="" span="">-sample>
D1<-diamonds diamonds1="" span="">-diamonds>
D1<-d1>% mutate(id = row_number())-d1>
D1
D2<-d1 span="">-d1>
D3<-d1 span="">-d1>
> set.seed(3311)
> diamonds1<-sample 10="" diamonds="" nrow="" span="">-sample>
> D1<-diamonds diamonds1="" span="">-diamonds>
>
> D1<-d1>% mutate(id = row_number())-d1>
> D1
# A tibble: 10 x 11
carat cut color clarity depth table price x y z id
1 0.6 Ideal F VS1 62.9 57 2142 5.35 5.31 3.35 1
2 0.55 Very Good E SI1 64.2 55 1417 5.18 5.2 3.33 2
3 1.01 Ideal D SI2 62.5 57 5206 6.39 6.35 3.98 3
4 0.33 Ideal G IF 60.9 57 946 4.45 4.48 2.72 4
5 0.91 Very Good E SI2 58.6 63 2963 6.38 6.32 3.72 5
6 0.91 Good G VVS2 64.1 58 4543 6.06 6.1 3.9 6
7 1.5 Good F VS2 63.6 55 13853 7.27 7.22 4.61 7
8 0.74 Ideal D VS2 61.8 56 3858 5.79 5.82 3.59 8
9 1.51 Premium H SI2 60.4 59 7864 7.3 7.27 4.4 9
10 0.45 Good E VS1 61.7 63 1241 4.88 4.91 3.02 10
>
> D2<-d1 span="">-d1>
> D3<-d1 span="">-d1>
문제는 union으로 D2, D3의 합집합인 데이터프레임을 구할 수 없다는 것입니다. 결과물은 list로 반환되는데, 그 모양이 본래 모습이 아닙니다. 하지만 당황할 필요가 없는게 이미 merge 명령어와 dplyr 패키지에서 옵션을 주어 얼마든지 교집합이나 합집합을 구할 수 있기 때문입니다.
차집합을 구하는 setdiff는 데이터 프레임 형태로 구할 수 있습니다. 이를 이용해서 NA값만 있는 값을 모아보겠습니다.
replace(D2$carat,D2$carat>1,NA)->D2$carat
D2
D5<-subset carat="">0)-subset>
D6<-setdiff span="">-setdiff>
D6
> replace(D2$carat,D2$carat>1,NA)->D2$carat
> D2
# A tibble: 8 x 11
carat cut color clarity depth table price x y z id
1 0.6 Ideal F VS1 62.9 57 2142 5.35 5.31 3.35 1
2 0.55 Very Good E SI1 64.2 55 1417 5.18 5.2 3.33 2
3 NA Ideal D SI2 62.5 57 5206 6.39 6.35 3.98 3
4 0.33 Ideal G IF 60.9 57 946 4.45 4.48 2.72 4
5 0.91 Very Good E SI2 58.6 63 2963 6.38 6.32 3.72 5
6 0.91 Good G VVS2 64.1 58 4543 6.06 6.1 3.9 6
7 NA Good F VS2 63.6 55 13853 7.27 7.22 4.61 7
8 0.74 Ideal D VS2 61.8 56 3858 5.79 5.82 3.59 8
>
> D5<-subset carat="">0)-subset>
> D6<-setdiff span="">-setdiff>
> D6
# A tibble: 2 x 11
carat cut color clarity depth table price x y z id
1 NA Ideal D SI2 62.5 57 5206 6.39 6.35 3.98 3
2 NA Good F VS2 63.6 55 13853 7.27 7.22 4.61 7
위의 예제에서 1캐럿 이상인 다이아몬드의 캐럿 값을 결측치로 만든 후 setdiff 를 이용해서 NA값이 있는 행만 따로 모았습니다. 이런 방식을 이용해서 결측치만 따로 모아서 분석하거나 혹은 결측치를 다른 데이터 프레임과 묶어 결측치를 채울 수 있습니다. 여기서는 D3에서 결측치를 채워보겠습니다.
D6<-d6 id="" span="">-d6>
D6<-merge by="c(" id="" span="">-merge>
D6
> D6<-d6 id="" span="">-d6>
> D6<-merge by="c(" id="" span="">-merge>
> D6
id carat cut color clarity depth table price x y z
1 3 1.01 Ideal D SI2 62.5 57 5206 6.39 6.35 3.98
2 7 1.50 Good F VS2 63.6 55 13853 7.27 7.22 4.61
여기서 D6에서 id만 남긴 이유는 중복되어 x/y 식으로 나타나는 것을 막기 위한 것입니다. 이후 rbind를 이용하면 완전한 데이터 셋을 복구할 수 있습니다.
D2<-rbind span="">-rbind>
D2
> D2<-rbind span="">-rbind>
> D2
# A tibble: 8 x 11
carat cut color clarity depth table price x y z id
1 0.6 Ideal F VS1 62.9 57 2142 5.35 5.31 3.35 1
2 0.55 Very Good E SI1 64.2 55 1417 5.18 5.2 3.33 2
3 0.33 Ideal G IF 60.9 57 946 4.45 4.48 2.72 4
4 0.91 Very Good E SI2 58.6 63 2963 6.38 6.32 3.72 5
5 0.91 Good G VVS2 64.1 58 4543 6.06 6.1 3.9 6
6 0.74 Ideal D VS2 61.8 56 3858 5.79 5.82 3.59 8
7 1.01 Ideal D SI2 62.5 57 5206 6.39 6.35 3.98 3
8 1.5 Good F VS2 63.6 55 13853 7.27 7.22 4.61 7
댓글
댓글 쓰기