关于R傍边的tapply
之前的博客《R数据阐明傍边的化整为零(Split-Apply-Combine)计策》有提到一些关于lapply, sapply, vapply的内容。对付tapply只是粗粗带过。
本日利用tapply的进程中碰着了一个很是令人狐疑的问题,于是不得不仔细研究一下这个tapply。
tapply的利用很简朴,当数据矩阵需要按个中的某一列,(可能几列,很少利用到)的内容来分组,在组内对数据需要利用指定的函数来运算时,就可以利用tapply。举个例子,有数据:
a<-data.frame(name=c("tom","sam","mik","ali"),age=c(8,9,8,9),score=c(50,100,70,90)) a name age score 1 tom 8 50 2 sam 9 100 3 mik 8 70 4 ali 9 90 |
假如我们需要按差异age来计较平均分的话,就可以利用到tapply.它的原型是,
tapply(X, INDEX, FUN = NULL, …, simplify = TRUE)
tapply(a[,"score"], a[,"age"], mean) 8 9 60 95 |
好像很简朴的对象。好了,我们此刻把数据调动一下,
> a<-data.frame(name=c("sam","tom","ali","mik"),age=c(9,8,9,8),score=c(100,50,90,70)) > a name age score 1 sam 9 100 2 tom 8 50 3 ali 9 90 4 mik 8 70 > tapply(a[,"score"], a[,"age"], mean) 8 9 60 95 |
我们调动了数据的排序,可是在利用了tapply之后,它输出的功效照旧与之前的一致。这一点很是有意思。这一点是否会导致一些潜在的错误呢?
我们还把数据变得更巨大一点。
> a<-data.frame(name=c("sam","tom","ali","mik"),age=c(9,8,9,8),math=c(100,50,90,70),verbal=c(90,60,96,80)) > a name age math verbal 1 sam 9 100 90 2 tom 8 50 60 3 ali 9 90 96 4 mik 8 70 80 |
我们此刻需要对差异年数段的后果举办求平均,下面的写法是否正确呢?
> ages<-unique(a$age) > ages [1] 9 8 > b<-matrix(nrow=length(ages),ncol=2) > rownames(b)<-ages > colnames(b)<-c("math","verbal") > for(i in 1:2){b[,i]<-tapply(a[,i+2],a[,"age"],mean)} |
我们来看当作果是什么?
> b math verbal 9 60 70 8 95 93 |
其实很容易看出来,这里的rownames对应呈现了错误。修悔改来也很容易,
> ages<-levels(as.factor(a$age)) > ages [1] "8" "9" > rownames(b)<-ages > b math verbal 8 60 70 9 95 93 |
这一看似很容易被识此外错误,但却很容易在大量数据处理惩罚时无法识别。就是因为对tapply没有领略透。tapply的排序要领是输入factor的levels。