2013-03-05 4 views
13

단일 Tapply 또는 집계 문 내에 두 개의 함수를 포함 할 수 있습니까?단일 Tapply 또는 집계 문에서 여러 함수

아래에서는 두 개의 tapply 문과 두 개의 집계 문을 사용합니다. 하나는 평균이고 다른 하나는 SD입니다.
성명서를 결합하는 것을 선호합니다.

my.Data = read.table(text = " 
    animal age  sex weight 
     1 adult female  100 
     2 young male  75 
     3 adult male  90 
     4 adult female  95 
     5 young female  80 
", sep = "", header = TRUE) 

with(my.Data, tapply(weight, list(age, sex), function(x) {mean(x)})) 
with(my.Data, tapply(weight, list(age, sex), function(x) {sd(x) })) 

with(my.Data, aggregate(weight ~ age + sex, FUN = mean) 
with(my.Data, aggregate(weight ~ age + sex, FUN = sd) 

# this does not work: 

with(my.Data, tapply(weight, list(age, sex), function(x) {mean(x) ; sd(x)})) 

# I would also prefer that the output be formatted something similar to that 
# show below. `aggregate` formats the output perfectly. I just cannot figure 
# out how to implement two functions in one statement. 

    age sex mean  sd 
adult female 97.5 3.535534 
adult male  90  NA 
young female 80.0  NA 
young male  75  NA 

저는 항상 두 개의 별도 명령문을 실행하고 출력을 병합 할 수 있습니다. 좀 더 편리한 해결책 인 이있을 것으로 기대하고있었습니다.

나는 대답 여기에 게시 아래에서 발견 : Apply multiple functions to column using tapply

f <- function(x) c(mean(x), sd(x)) 
do.call(rbind, with(my.Data, tapply(weight, list(age, sex), f))) 

그러나, 행 또는 열이 모두 표시되어 있습니다.

 [,1]  [,2] 
[1,] 97.5 3.535534 
[2,] 80.0  NA 
[3,] 90.0  NA 
[4,] 75.0  NA 

나는 plyr 패키지에서 솔루션은 위의 링크에 게시 된 기본 R.에서 솔루션을 선호하는 것이다. 위의 출력에 올바른 행 및 열 머리글을 추가 할 수 있다면 완벽 할 것입니다.

답변

14

그러나 이러한이 있어야합니다

with(my.Data, aggregate(weight, list(age, sex), function(x) { c(MEAN=mean(x), SD=sd(x))})) 

with(my.Data, tapply(weight, list(age, sex), function(x) { c(mean(x) , sd(x))})) 
# Not a nice structure but the results are in there 

with(my.Data, aggregate(weight ~ age + sex, FUN = function(x) c(SD = sd(x), MN= mean(x)))) 
    age sex weight.SD weight.MN 
1 adult female 3.535534 97.500000 
2 young female  NA 80.000000 
3 adult male  NA 90.000000 
4 young male  NA 75. 

원리가 준수하는 벡터 또는 목록 중 하나가 될 수 있지만,이 함수의 연속적인 호출 할 수 없다 함수의 반환 "한 가지"하는 것입니다 전화. 당신이 data.table 사용하려는 경우

+0

감사합니다! 두 개의 집계 문이 작동합니다. tapply 문은 작동하는 것처럼 보이지 않지만 집계 방법을 사용할 수 있습니다. –

+1

글쎄, 나는 그것이 "잘 작동한다고"생각한다. with (my.Data, tapply (weight, list (age, sex), function (x) {c (mean (x), sd (x))})) [1,1]'을 시도해보고 목록의 매트릭스를 볼 수 있습니다. –

+0

나는 본다. 고맙습니다. 그리고 전체 문장을 colnames() 또는 rownames()에 넣으면 레이블이 생깁니다. –

8

, 그것은 with 가지고 by은 바로 내장 :

library(data.table) 
myDT <- data.table(my.Data, key="animal") 


myDT[, c("mean", "sd") := list(mean(weight), sd(weight)), by=list(age, sex)] 


myDT[, list(mean_Aggr=sum(mean(weight)), sd_Aggr=sum(sd(weight))), by=list(age, sex)] 
    age sex mean_Aggr sd_Aggr 
1: adult female  96.0 3.6055513 
2: young male  76.5 2.1213203 
3: adult male  91.0 1.4142136 
4: young female  84.5 0.7071068 

내가 SD에 대한 NA 값을 가질하지 않도록 설정 약간 다른 데이터를 사용

4

Reshape는 두 가지 기능을 전달합니다. reshape2하지 않습니다.

library(reshape) 
my.Data = read.table(text = " 
    animal age  sex weight 
     1 adult female  100 
     2 young male  75 
     3 adult male  90 
     4 adult female  95 
     5 young female  80 
", sep = "", header = TRUE) 
my.Data[,1]<- NULL 
(a1<- melt(my.Data, id=c("age", "sex"), measured=c("weight"))) 
(cast(a1, age + sex ~ variable, c(mean, sd), fill=NA)) 

#  age sex weight_mean weight_sd 
# 1 adult female  97.5 3.535534 
# 2 adult male  90.0  NA 
# 3 young female  80.0  NA 
# 4 young male  75.0  NA 

난 그냥 어제 this을 언급 @Ramnath,이 빚.

6

공유 목적으로 SQL을 잘 알고 있다면 "sqldf"패키지를 고려해보십시오. (강조는 당신이 알 필요가 없기 때문에, 예를 들어, 그 mean 당신이 원하는 결과를 얻기 위하여 avg입니다 추가.)

sqldf("select age, sex, 
     avg(weight) `Wt.Mean`, 
     stdev(weight) `Wt.SD` 
     from `my.Data` 
     group by age, sex") 
    age sex Wt.Mean Wt.SD 
1 adult female 97.5 3.535534 
2 adult male 90.0 0.000000 
3 young female 80.0 0.000000 
4 young male 75.0 0.000000