지난번과 같은 예제를 사용해 보겠다.

 

> fruit<-c("banana","apple","apple","banana","orange","banana")
> weight<-c(2,3,3,5,2,5)

 

바나나 데이터, 애플 데이터, 오렌지 데이터를 나누고 싶다. 이럴 때 split()를 쓴다.

 

> split(weight,fruit)
$apple
[1] 3 3
$banana
[1] 2 5 5
$orange
[1] 2

 

보는 바와 같이 결과는 리스트 형식으로 나온다. 이제 lapply()를 써서 분할된 각각의 데이터로 평균이든 합이든 구할 수 있다.

 

> lapply(split(weight,fruit),mean) 
$apple 
[1] 3 
$banana 
[1] 4 
$orange 
[1] 2

 

sapply()도 당연히 쓸 수 있다.

 

> sapply(split(weight,fruit),mean) 
 apple banana orange  
     3      4      2 

 

입력값이 벡터가 아니라 데이터 프레임이라도 상관 없다. 나이 변수를 하나 더 만들어서 컬럼 세 개짜리 데이터 프레임을 만들어 보자. (근데 과일 나이가 여섯살, 일곱살 이게 가능한가? 암튼)

 

> age<-c(4,5,4,6,7,7) 
> fruits<-data.frame(fruit,weight,age)
> fruits 
   fruit weight age 
1 banana      2   4 
2  apple      3   5 
3  apple      3   4 
4 banana      5   6 
5 orange      2   7 
6 banana      5   7

 

split() 함수의 두번째 argument는 factor니깐 세 개의 변수 중에 무엇을 factor로 할 건지를 정해야 한다. data.frame의 규칙을 따라 다음과 같이 $ 표시를 쓴다. 과일 이름을 기준으로 할거니까,

 

> split(fruits,fruits$fruit) 
$apple 
  fruit weight age 
2 apple      3   5 
3 apple      3   4 

$banana 
   fruit weight age 
1 banana      2   4 
4 banana      5   6 
6 banana      5   7 

$orange 
   fruit weight age 
5 orange      2   7

 

이제 lapply()를 쓸 수 있는데 이건 벡터가 아닌 데이터 프레임의 리스트이기 때문에 그냥은 못 쓴다. 칼럼별로 평균을 구하는 colMeans() 함수를 이용해 사용자 정의 함수를 하나 만든다.

 

> lapply(s,function(x) colMeans(x[,c("weight","age")])) 
$apple 
weight    age  
   3.0    4.5  

$banana 
  weight      age  
4.000000 5.666667  

$orange 
weight    age  
     2      7 

 

매우 비슷하게 sapply() 함수도 쓸 수 있다. 

 

> sapply(s,function(x) colMeans(x[,c("weight","age")])) 
       apple   banana orange 
weight   3.0 4.000000      2 
age      4.5 5.666667      7
Posted by jujaeuk
,