이 절에서는 주어진 데이터를 조건에 따라 분리하는 split(), subset() 함수 그리고 분리되어 있는 데이터를 공통된 값에 따라 병합하는 merge() 함수에 대해서 설명한다. 데이터를 분리하는 함수를 사용하면 조건에 만족하는 데이터를 미리 선택할 수 있어 이어지는 처리를 쉽게 할 수 있다. 또, 분리된 데이터는 merge()로 재병합할 수 있다. 다음에 이들 함수의 특징을 요약했다.
함수 | 특징 |
split() | 주어진 조건에 따라 데이터를 분리한다. |
subset() | 주어진 조건을 만족하는 데이터를 선택한다. |
merge() | 데이터를 공통된 값에 기준해 병합한다. |
split()
split()은 조건에 따라 데이터를 분리하는데 사용한다ㅣ.
-split : 주어진 기준에 따라 데이터를 분리한다.
split(
x, #분리할 벡터 또는 데이터 프레임
f #분리할 기준을 저장한 벡터
)
다음은 iris 데이터를 iris$Species에 따라 분리하고 결과를 리스트에 저장하는 예다.
>split(iris, iris$Species) $setosa Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa ... $versicolor Sepal.Length Sepal.Width Petal.Length Petal.Width Species 51 7.0 3.2 4.7 1.4 versicolor 52 6.4 3.2 4.5 1.5 versicolor ... $virginica Sepal.Length Sepal.Width Petal.Length Petal.Width Species 101 6.3 3.3 6.0 2.5 virginica 102 5.8 2.7 5.1 1.9 virginica ... |
split()의 실행 결과가 리스트므로, split() 후 lapply()를 적용하면 iris의 종별 Sepal.Length의 평균을 구할 수 있다. 다음 코드를 앞서 설명한 tapply()의 경우와 비교해보기 바란다.
>lapply(split(iris$Sepal.Length, iris$Species), mean) $setosa [1] 5.006 $versicolor [1]5.936 $virginica [1]6.588 |
subset()
subset()은 split()과 유사하지만 전체를 부분으로 구분하는 대신 조건을 만족하는 특정 부분만 취하는 용도로 사용한다.
-subset : 조건을 만족하는 벡터, 행렬, 데이터 프레임의 일부를 반환한다.
subset(
x, #일부를 취할 객체
subset #데이터를 취할 것인지 여부
)
subset(
x,
subset,
select #데이터 프레임의 경우 선택하고자 하는 컬럼
)
다음은 iris에서 setosa 종만 뽑아내는 예다.
>subset(iris, Species=="setosa") Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa ... |
"벡터 연산"에서 살펴봤듯이 벡터 간 연산에서의 AND, OR는 &&, ||가 아니라 &,|를 사용해야 한다. 따라서 subset()에서 2개 이상의 조건을 조합할 때는 &나 |를 사용한다. 다음은 setosa종에서 Sepal.Length가 5.0 이상인 행을 추출하는 예다.
>subset(iris, Species=="setosa"&Sepal.Length > 5.0) Sepal.Length Sepal.Width Petal.Length Petal.Width Species 1 5.1 3.5 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa ... |
subset에 select 인자를 지정하면 특정 컬럼을 선택하거나 제외할 수 있다. 다음은 Sepal.Length와 Species 컬럼을 iris에서 선택하여 출력한 예다.
>subset(iris, select=c(Sepal.Length, Species)) Sepal.Length Species 1 5.1 setosa 2 4.9 setosa 3 4.7 setosa ... |
반대로 특정 컬럼을 제외하고자 한다면 -를 컬럼 이름 앞에 붙인다.
>subset(iris, select=-c(Sepal.Length, Species)) Sepal.Width Petal.Length Petal.Width 1 3.5 1.4 0.2 2 3.0 1.4 0.2 ... |
select에서 컬럼을 제외하는 방법을 names()와 %in%을 사용하여 제외하는 방법과 비교해서 알아두기 바란다.
>iris(,!names(iris) %in% c("Sepal.Length","Species")) Sepal.Width Petal.Length Petal.Width 1 3.5 1.4 0.2 2 3.0 1.4 0.2 ... |
데이터 병합
merge()는 두 데이터 프레임을 공통된 값을 기준으로 묶는 함수다. merge()는 데이터베이스에서 join과 같은 역할을 한다.
-merge: 공통된 컬럼명 또는 행 이름에 따라 데이터 프레임을 병합한다.
merge(
x, #병합할 데이터 프레임
y #병합할 데이터 프레임
)
merge(
x,
y,
by, #병합 기준으로 사용할 컬럼
#데이터프레임 x, y에서 병합에 사용할 컬럼이 각각 다르다면 by.x, by.y에 이를 지정
by.x=by,
by.y=by,
#all은 공통된 값이 x,y 중 한쪽에 없을 때의 처리를 뜻한다. 기본값은 FALSE로 x,y 모두에
#공통된 데이터가 있을때만 해당 행이 병합 결과에 포함된다. all=TRUE면
#x,y 중 어느 한쪽에 공통된 값을 가지는 행이 없을 때 해당 쪽을 NA로 채워 병합하여
#결과적으로 x,y의 전체 행이 결과에 포함된다.
all=FALSE,
#all.x, all.y를 통해 x,y 중 특정 쪽에 공통된 값이 없더라도 항상 결과에 포함되게 할 수 있다.
all.x,
all.y
)
다음은 이름(name)컬럼을 기준으로 수학 점수가 저장된 데이터 프레임과 영어 점수가 저장된 데이터 프레임을 병합한 예다. x와 y에 name값이 서로 다른 순서로 저장되어 있으나 공통된 name값을 기준으로 점수가 잘 병합된 것을 볼 수있다.
>x<-data.frame(name=c("a","b","c"), math=c(1,2,3)) >y<-data.frame(name=c("c","b","a"), english=c=4,5,6)) name math english 1 a 1 6 2 b 2 5 3 c 3 4 |
merge()는 cbind()와는 다르다. 앞의 코드는 두 개의 데이터 프레임을 합칠 떄 공통되는 컬럼인 name을 기준으로 데이터를 합치지만 cbind()는 다음에 보인 것처럼 단순히 컬럼을 합칠 뿐이다.
>x<-data.frame(name=c("a","b","c"), math=c(1,2,3)) >y<-data.frame(name=c("c","b","a"), english=c=4,5,6)) >cbind(x,y name math name english 1 a 1 c 4 2 b 2 b 5 3 c 3 a 6 |
merge() 수행 시 공통된 값이 한쪽에만 있는 경우에는 반대편 데이터가 비게 되고 이 경우 해당 행은 병합 결과에서 빠진다. 그러나 이 경우에도 데이터가 비어 이쓴 쪽의 값을 NA로 채우면서 전체 데이터를 모두 병합하고 싶다면 all 인자에 TRUE를 지정한다.
다음에 all=FALSE(기본값)인 경우와 all=TRUE인 경우의 비교를 보였다. all=FALSE인 경우 공통된 name이 양측에 포함된 "a","b"만 결과에 나타나며, all=True인 경우 공통된 값이 없는 쪽에 NA가 채워지면서 x,y의 전체 행이 결과에 포함된다.
>x<-data.frame(name=c("a","b","c"), + math=c(1,2,3)) >x<-data.frame(name=c("a","b","c"), + english=c(4,5,6)) >merge(x,y) name math english 1 a 1 4 2 b 2 5 >merge(x,y,all=TRUE) name math english 1 a 1 4 2 b 2 5 3 c 3 NA 4 d NA 6 |
R을 이용한 데이터 처리&분석 실무 中
'R > R을 이용한 데이터 처리&분석 실무' 카테고리의 다른 글
데이터 구조의 변형과 요약 (0) | 2020.02.03 |
---|---|
데이터 정렬 (0) | 2020.02.03 |
apply 계열 함수 - 2 (0) | 2020.02.02 |
apply 계열 함수 - 1 (0) | 2020.02.01 |
데이터 프레임의 행과 컬럼 합치기 (0) | 2020.01.31 |