【3.3.3】apply、tapply、lapply、sapply、mapply、table等函数进行分组统计

对矩阵一般的分组统计方式不能满足的时候,我们就需要借助一些函数来帮忙,这里讲介绍apply、tapply、lapply、sapply、mapply、table等函数进行分组统计。

一 、apply函数

(对一个数组按行或者按列进行计算): 使用格式为:

apply(X, MARGIN, FUN, ...)

其中X为一个数组;MARGIN为一个向量(表示要将函数FUN应用到X的行还是列),若为1表示取行,为2表示取列,为c(1,2)表示行、列都计算。

示例代码:

> ma <- matrix(c(1:4, 1, 6:8), nrow = 2)
> ma
 [,1] [,2] [,3] [,4]
[1,] 1 3 1 7
[2,] 2 4 6 8
> apply(ma, c(1,2), sum)
 [,1] [,2] [,3] [,4]
[1,] 1 3 1 7
[2,] 2 4 6 8
> apply(ma, 1, sum)
[1] 12 20
> apply(ma, 2, sum)
[1] 3 7 7 15

取只要有一个丰度值大于1%的otu
myfun<-function(x){sum(x>0.01)};
t80<-all_80_percent[,2:(nn+1)];
all_80_percent_1<-all_80_percent[as.logical(apply(t80,1,myfun)),]

大于0.01为存在,0.7为普遍存在
myfun<-function(x){sum(x>=0.01)};
m<-(147-99+1)*0.7;
cun_5<-bac_b[(apply(total,1,myfun)>=m),];

二、 函数tapply

(进行分组统计):

使用格式为:

tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE) 

#对x进行操作罗其中X通常是一向量;INDEX是一个list对象,且该list中的每一个元素都是与X有同样长度的因子;FUN是需要计算的函数;simplify是逻辑变量,若取值为TRUE(默认值),且函数FUN的计算结果总是为一个标量值,那么函数tapply返回一个数组;若取值为FALSE,则函数tapply的返回值为一个list对象。需要注意的是,当第二个参数INDEX不是因子时,函数 tapply() 同样有效,因为必要时 R 会用 as.factor()把参数强制转换成因子。

示例代码:

 > fac <- factor(rep(1:3, length = 17), levels = 1:5)
 > fac
 [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
 Levels: 1 2 3 4 5
 > tapply(1:17, fac, sum)
 1 2 3 4 5
 51 57 45 NA NA
 > tapply(1:17, fac, sum, simplify = FALSE)
 $`1`
 [1] 51
 $`2`
 [1] 57
 $`3`
 [1] 45
 $`4`
 NULL
 $`5`
 NULL
 > tapply(1:17, fac, range)
 $`1`
 [1] 1 16
 $`2`
 [1] 2 17
 $`3`
 [1] 3 15
 $`4`
 NULL
 $`5`
 NULL
 #利用tapply实现类似于excel里的数据透视表的功能:
 > da
 year province sale
 1 2007 A 1
 2 2007 B 2
 3 2007 C 3
 4 2007 D 4
 5 2008 A 5
 6 2008 C 6
 7 2008 D 7
 8 2009 B 8
 9 2009 C 9
 10 2009 D 10
 > attach(da)
 > tapply(sale,list(year,province))
 [1] 1 4 7 10 2 8 11 6 9 12
 > tapply(sale,list(year,province),mean)
 A B C D
 2007 1 2 3 4
 2008 5 NA 6 7
 2009 NA 8 9 10

三 、函数table

(求因子出现的频数): 使用格式为:

table(..., exclude = if (useNA == "no") c(NA, NaN), useNA = c("no",

“ifany”, “always”), dnn = list.names(…), deparse.level = 1)

其中参数exclude表示哪些因子不计算。

示例代码:

> d <- factor(rep(c("A","B","C"), 10), levels=c("A","B","C","D","E"))
> d
[1] A B C A B C A B C A B C A B C A B C A B C A B C A B C A B C
Levels: A B C D E
> table(d)
d
A B C D E
10 10 10 0 0
> table(d, exclude="B")
d
A C D E
10 10 0 0

四、函数lapply与函数sapply:

lapply的使用格式为:

lapply(X, FUN, …)

lapply的返回值是和一个和X有相同的长度的list对象,这个list对象中的每个元素是将函数FUN应用到X的每一个元素。其中X为List对象(该list的每个元素都是一个向量),其他类型的对象会被R通过函数as.list()自动转换为list类型。 函数sapply是函数lapply的一个特殊情形,对一些参数的值进行了一些限定,其使用格式为:

sapply(X, FUN,…, simplify = TRUE, USE.NAMES = TRUE) sapply(, simplify = FALSE, USE.NAMES = FALSE) 和lapply()的返回值是相同的。如果参数simplify=TRUE,则函数sapply的返回值不是一个list,而是一个矩阵;若simplify=FALSE,则函数sapply的返回值仍然是一个list。

示例代码:

 > x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE))
 > lapply(x, quantile)
 $a
 0% 25% 50% 75% 100%
 1.00 3.25 5.50 7.75 10.00
 $beta
 0% 25% 50% 75% 100%
 0.04978707 0.25160736 1.00000000 5.05366896 20.08553692
 $logic
 0% 25% 50% 75% 100%
 0.0 0.0 0.5 1.0 1.0
 > sapply(x, quantile,simplify=FALSE,use.names=FALSE)
 $a
 0% 25% 50% 75% 100%
 1.00 3.25 5.50 7.75 10.00
 $beta
 0% 25% 50% 75% 100%
 0.04978707 0.25160736 1.00000000 5.05366896 20.08553692
 $logic
 0% 25% 50% 75% 100%
 0.0 0.0 0.5 1.0 1.0
 #参数simplify=TRUE的情况
 > sapply(x, quantile)
 a beta logic
 0% 1.00 0.04978707 0.0
 25% 3.25 0.25160736 0.0
 50% 5.50 1.00000000 0.5
 75% 7.75 5.05366896 1.0
 100% 10.00 20.08553692 1.0

函数sapply也可以当作函数lapply的一个总结

 > x <- list(a = 1:4, b = rnorm(10), c = rnorm(20, 1), d = rnorm(100, 5))
 > lapply(x, mean)
 $a
 [1] 2.5
 $b
 [1] 0.06082667
 $c
 [1] 1.467083
 $d
 [1] 5.074749
 > sapply(x, mean)
 a b c d
 2.50000000 0.06082667 1.46708277 5.07474950
 > mean(x)
 [1] NA
 Warning message:
 In mean.default(x) : argument is not numeric or logical: returning NA

五、函数mapply:

函数mapply是函数sapply的变形版,mapply 将函数 FUN 依次应用每一个参数的第一个元素、第二个元素、第三个元素上。函数mapply的使用格式如下: mapply(FUN, …, MoreArgs = NULL, SIMPLIFY = TRUE,USE.NAMES = TRUE) 其中参数MoreArgs表示函数FUN的参数列表。

示例代码:

 > mapply(rep, times=1:4, x=4:1)
 [[1]]
 [1] 4
 [[2]]
 [1] 3 3
 [[3]]
 [1] 2 2 2
 [[4]]
 [1] 1 1 1 1

#直接使用函数rep的结果:

> rep(1:4,1:4)
[1] 1 2 2 3 3 3 4 4 4 4

参考资料:

菜鸟的成长 http://blog.sina.com.cn/s/blog_6caea8bf0100xkpg.html

部分内容来自于Roger D. Peng的《Computing for Data Analysis》

药企,独角兽,苏州。团队长期招人,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn