R语言中lapply、apply、tapply、mapply的区别是啥?

新手只会用apply,看到lapply、apply、tapply、mapply不知道都有啥区别,有人讲解下吗

请先 登录 后评论

1 个回答

admin

网上找来的一个答案
apply用法: apply(x,MARGIN,FUN,…)

其中,x为数据对象,MARGIN是维度的下标,FUN则是由你指定的函数,包括了它想传达给FUN的参数,在矩阵或者数据框中,MARGIN=1表示对行进行处理,而MARGIN=2则表示对列进行处理。
如对矩阵进行处理:

dat1<-matrix(1:8,2,4) 
dat1 
[,1] [,2] [,3] [,4] 
[1,] 1 3 5 7 
[2,] 2 4 6 8 
apply(dat1,MARGIN=1,sum) #对dat1的行进行求和 
[1] 16 20 
apply(dat1,MARGIN=2,mean) #对dat1的列求均值 
[1] 1.5 3.5 5.5 7.5

对数据框进行处理:

w<-c(40,50,60,70,75,90) 
h<-c(148,150,170,166,67,191) 
a<-(1,2,2,1,1,2) 
dat2<-data.frame(a=a,h=h,w=w) 
dat2 
a h w
1 1 148 40
2 2 150 50
3 2 170 60
4 1 166 70
5 1 67 75
6 2 191 90
sum_add2<-function(x){
sum(x)+2
}
apply(dat2,MARGIN=1,sum_aad2) #自定义函数
[1] 191 204 234 239 145 285 
apply(dat2,1,function(x) sum(x)+2)
[1] 191 204 234 239 145 285
apply(dat2,1,function(x,y) mean(x)/y,y=10)
[1] 6.300000 6.733333 7.733333 7.900000 4.766667 9.433333
lapply用法:

lapply遍历列表向量内的每个元素,并且使用指定函数来对其元素进行处理。返回列表向量。在处理数据框的时候,lapply非常实用,lapply没有MARGIN参数,它的用法是: lapply(list, function, ...)

lapply(dat2,mean)
$a
[1] 1.5

$h
[1] 148.6667

$w
[1] 64.16667

可以看到它对dat2的每一列进行了求和处理,其返回的也是一个列表 非列表的集合:如果被处理的集合不是list,则lapply会先使用as.list函数将此集合转化为list再进行处理

x<-1:5
> lapply(x,rnorm,10)
[[1]]
[1] 10.22798

[[2]]
[1] 11.26147 10.35282

[[3]]
[1] 9.786493 10.506313 10.497254

[[4]]
[1] 10.753250 9.929645 9.378586 11.721369

[[5]]
[1] 10.66999 10.29661 10.74270 10.32963 8.40919

tapply的用法: tapply(x,INDEX,FUN=NULL,…,simplify=TRUE)

对不规则的的数组应用函数(进行分组统计)。当数据矩阵需要按其中某一列的内容来分组,在组内读数据需要使用指定的函数运算时,则可以采用tapply。

其中,x为原子向量,INDEX为长度和x一样的因子列表,FUN指的运用什么函数,参数simplify决定返回的结果类型,…为传递给FUN的参数。

我们采用R内部数据空气质量(airquality),若我想知道5-9月份的平均温度,则可采用:

data(airquality)
tapply(airquality$Temp,airquality$Month,mean)
5 6 7 8 9 
65.54839 79.10000 83.90323 83.96774 76.90000

返回了5-9月份的平均气温

tapply(airquality$Solar.R,airquality$Day,mean,na.rm=T)
1 2 3 4 5 6 7 8 
199.0000 174.8000 177.4000 197.2500 163.3333 223.3333 241.8000 217.6000 
9 10 11 12 13 14 15 16 
203.8000 234.6000 192.7500 244.2000 224.8000 215.6000 122.2000 218.6000 
17 18 19 20 21 22 23 24 
228.0000 108.4000 222.2000 158.4000 132.4000 137.4000 161.0000 179.4000 
25 26 27 28 29 30 31 
136.4000 176.4000 106.7500 143.6000 182.8000 214.8000 240.3333

利用传递的参数消除数据内部NA的影响。

再来看一个例子:

data(mtcars)
mtcars[1,]
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21 6 160 110 3.9 2.62 16.46 0 1 4 4

我们看到了数据的第一列为汽车的类型,第二列为mpg(每英里油耗),第三列为汽车汽缸数量,分别有4,6,8个汽缸,第4列为速度。如果我想统计不同的气缸数的车型的平均油耗和最大速度的范围,则也可以采用tapply函数:

a<-tapply(mtcars$mpg,mtcars$cyl,mean)
sort(a)
8 6 4 
15.10000 19.74286 26.66364

随着气缸数的增加,每英里的平均油耗下降,再看看速度:

tapply(mtcars$hp,mtcars$cyl,range)
$`4`
[1] 52 113

$`6`
[1] 105 175

$`8`
[1] 150 335
mapply

mappl可以看成是sapply的多变量版本,其用法是:mapply(FUN,...MoreArgs=NULL,SIMPLIFY=TRUE,USE.NAMES=TRUE) 将FUN依次应用到每一个参数的第一个元素,第二个元素,第三个…,其中MoreArgs表示函数的参数列表

mapply(rep,1:4,4:1)
[[1]]
[1] 1 1 1 1

[[2]]
[1] 2 2 2

[[3]]
[1] 3 3

[[4]]
[1] 4
mapply(seq,from=1:6,to=10,by=1:2)
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10

[[2]]
[1] 2 4 6 8 10

[[3]]
[1] 3 4 5 6 7 8 9 10

[[4]]
[1] 4 6 8 10

[[5]]
[1] 5 6 7 8 9 10

[[6]]
[1] 6 8 10

apply系列的函数的的处理对象和方式都有所不同,只要选择好合适的函数,就能给我们带来方便。

请先 登录 后评论