본문 바로가기
9.유용한 함수모음/유용한 함수

[R 유용한 함수] 데이터의 그룹을 나눠주는 split 함수

by makhimh 2020. 1. 18.
반응형

데이터의 그룹을 나눠주는 split 함수


R에서 제공하는 split 함수는 데이터를 그룹으로 나눠줍니다. 말로 설명이 어려워서 예제를 통해 이해해봅시다. 먼저 아래와 같이 사람 열명의 이름으로 되어 있는 데이터를 만들어봅시다. 


name=c("KKH","LIK","JJI","AHK","BBK","SYJ","BJW","JDK","KII","SSI")


이제 이 사람들을 A,B,C 세개의 그룹으로  나눌 것입니다. 그룹 배정이 아래와 같이 되었다고 합시다. (factor가 아니라 vector 형태로 입력해도 됩니다. vector로 입력할 경우 drop 옵션 사용이 불가합니다. 이후 설명하겠습니다.)


group=factor(c("A","B","A","C","C","A","B","B","A","C"))


spilit 함수를 적용하면 각 그룹 안에 사람 이름이 저장된 '리스트'를 만들어줍니다. 


> name_group=split(name,group)

> name_group

$A

[1] "KKH" "JJI" "SYJ" "KII"


$B

[1] "LIK" "BJW" "JDK"


$C

[1] "AHK" "BBK" "SSI"


상당히 유용한 함수입니다. 분류 대상이 되는 데이터와, 그룹 데이터는 문자형 뿐 아니라 숫자형으로도 가능합니다. group 이름을 A,B,C 대신 1,2,3으로 입력해도 됩니다. 


이번에는 split 함수의 옵션을 살펴봅시다. 


split(x, f, drop = FALSE, sep = ".", lex.order = FALSE, ...)


아래는 옵션에 대한 설명입니다. 


x : 데이터

f : 그룹 데이터(vector, factor, list 셋 다 올 수 있음)

drop : f 에서 사용되지 않는 level을 제거할지 않을지 결정

sep : f가 list로 입력될 경우 사용됩니다. 

lex.order : f가 list로 입력될 경우 사용됩니다. 


drop 옵션부터 하나씩 살펴봅시다. 


drop 옵션을 설명드리겠습니다. 아래와 같이 group이 요인으로 입력되었고, level이 A,B,C,D 네가지라고 합시다. 하지만 실제 데이터가 존재하는 level은 A,B,C입니다. 먼저 drop 을 FALSE로 해봅시다. 


name=c("KKH","LIK","JJI","AHK","BBK","SYJ","BJW","JDK","KII","SSI")

group=factor(c("A","B","A","C","C","A","B","B","A","C"),

             levels=c("A","B","C","D"))

name_group=split(name,group,drop=FALSE)


아래와 같이 데이터가 없는 level "D"도 리스트에 포함됩니다. 


> name_group=split(name,group,drop=FALSE)

> name_group

$A

[1] "KKH" "JJI" "SYJ" "KII"


$B

[1] "LIK" "BJW" "JDK"


$C

[1] "AHK" "BBK" "SSI"


$D

character(0)


drop을 TRUE로 할 경우 아래와 같이 level "D"는 사라집니다. 


> name_group=split(name,group,drop=TRUE)

> name_group

$A

[1] "KKH" "JJI" "SYJ" "KII"


$B

[1] "LIK" "BJW" "JDK"


$C

[1] "AHK" "BBK" "SSI"


sep옵션은 f가 list 형태일 경우 사용됩니다. 먼저 f가 list일 경우 어떤 일이 벌어지는지 알아봅시다. 


name=c("KKH","LIK","JJI","AHK","BBK","SYJ","BJW","JDK","KII","SSI")

group=list(c("A","B"),c("C","D"))

name_group=split(name,group)


group을 list로 정의했습니다. list안에는 A와 B를 원소로 갖는 벡터와 C,D를 원소로 갖는 벡터를 넣었습니다. 결과는 아래와 같습니다. 


> name_group

$A.C

[1] "KKH" "JJI" "BBK" "BJW" "KII"


$B.C

character(0)


$A.D

character(0)


$B.D

[1] "LIK" "AHK" "SYJ" "JDK" "SSI"


먼저 리스트의 각 벡터들이 name의 원소에 하나씩 매칭되게 됩니다. 아래와 같이 됩니다. 


"KKH","LIK","JJI","AHK","BBK","SYJ","BJW","JDK","KII","SSI"

A B A B A B A B A B 

C D C D C D C D C D


결과적으로 각 이름들은 두개의 요인을 갖게됩니다. 예를들면 KKH는 A와 C, LIK는 B와 D 라는 요인을 갖습니다. 이 요인들은 . 으로 결합됩니다. 더 자세히 이야기하면 interaction 함수가 사용된 것인데 링크를 참고하세요. 


이때 두 요인을 결합하는 문자를 sep 옵션으로 설정하는 것입니다. sep옵션을 : 로 설정해보겠습니다. 


> name_group=split(name,group,sep=":")

> name_group

$`A:C`

[1] "KKH" "JJI" "BBK" "BJW" "KII"


$`B:C`

character(0)


$`A:D`

character(0)


$`B:D`

[1] "LIK" "AHK" "SYJ" "JDK" "SSI"


마지막으로 lex.order 옵션은 요인이 결합된 후 그 순서에 대한 옵션입니다. 위 순서를 보면 AC BC AD BD 순입니다. 요인 1의 알파벳순서 A B가 먼저 반복되고, C D 알파벳 순으로 따라 붙습니다. lex.order을 TRUE로 설정해봅시다. 


> name_group=split(name,group,sep=":",lex.order=TRUE)

> name_group

$`A:C`

[1] "KKH" "JJI" "BBK" "BJW" "KII"


$`A:D`

character(0)


$`B:C`

character(0)


$`B:D`

[1] "LIK" "AHK" "SYJ" "JDK" "SSI"


lex.order을 TRUE로 한 경우 A 이후에 C,D가 오고 B 이후에 다시 C,D가 옵니다. 

반응형

댓글