在R语言中,有些函数由于名字相似,或者功能相似,容易混淆。因此,我计划记录一些在R中易混淆的函数,相应的文章题目都是冠以易混淆函数札记。这是这个系列的第一篇。
在R语言中函数中带有apply名字的函数一共有4个,分别为apply
, lappy
, sapply
, tappy
。它们有着相似的名字,用法也有一些相似,容易混淆,因此,写这篇文章的目的就是帮助读者更好的区分这3个函数。
这篇文章中用的数据集是R中自带的mtcars数据集,可以直接调用。由于该数据集列数较多,为了方便理解,我们只取其mpg
, cyl
, hp
列,分别表示汽车每加仑汽油跑的里程(单位mile)、气缸数、汽车马力。并将这些列赋值给cars
变量
> cars <- mtcars[,c("mpg","cyl","hp")] # 赋值给cars
> head(cars) # 使用head函数查看前几行数据
mpg cyl hp
Mazda RX4 21.0 6 110
Mazda RX4 Wag 21.0 6 110
Datsun 710 22.8 4 93
Hornet 4 Drive 21.4 6 110
Hornet Sportabout 18.7 8 175
Valiant 18.1 6 105
除非特别指出,否则后面的函数都是针对的cars变量的数据。
下面逐个介绍这些函数。
apply 函数
apply这个单词的意思是应用。它的作用是将指定函数应用于数组或矩阵的行或者列
用法是apply(X, MARGIN, FUN, ...)
参数解释
x : 待分析的数据(dataframe格式)
MARGIN : 1 表示为对行进行应用,2表示对列进行应用,c(1,2)则表示既对行又对列进行应用
FUN : 要应用的函数
比如我要对每列求标准差(R 中 内置了sd
函数),并将结果赋值给colsd
> colsd <- apply(cars,2,sd) # 2表示对列处理
# 结果
> colsd
mpg cyl hp
6.026948 1.785922 68.562868
lapply 函数与sapply函数
apply函数针对的是某一行或者几行或者某一列或几列数据,而lapply 函数则可以遍历列表向量内的每个元素,并且使用指定函数来对其元素进行处理。返回列表向量(不是dataframe)。可以认为lappy中的l代表的就是list。
例如我想将所有数据都减去2然后除以10,并将结果赋值给change函数
用法 lapply(X, FUN, ...)
参数解释
和apply一样
> change <- lapply(cars,function(x){(x-2)/10})
> $mpg
[1] 1.90 1.90 2.08 1.94 1.67 1.61 1.23 2.24 2.08 1.72 1.58 1.44
[13] 1.53 1.32 0.84 0.84 1.27 3.04 2.84 3.19 1.95 1.35 1.32 1.13
[25] 1.72 2.53 2.40 2.84 1.38 1.77 1.30 1.94
$cyl
[1] 0.4 0.4 0.2 0.4 0.6 0.4 0.6 0.2 0.2 0.4 0.4 0.6 0.6 0.6 0.6
[16] 0.6 0.6 0.2 0.2 0.2 0.2 0.6 0.6 0.6 0.6 0.2 0.2 0.2 0.6 0.4
[31] 0.6 0.2
$hp
[1] 10.8 10.8 9.1 10.8 17.3 10.3 24.3 6.0 9.3 12.1 12.1 17.8
[13] 17.8 17.8 20.3 21.3 22.8 6.4 5.0 6.3 9.5 14.8 14.8 24.3
[25] 17.3 6.4 8.9 11.1 26.2 17.3 33.3 10.7
# 结果
> head(change)
$mpg
[1] 1.90 1.90 2.08 1.94 1.67 1.61 1.23 2.24 2.08 1.72 1.58 1.44
[13] 1.53 1.32 0.84 0.84 1.27 3.04 2.84 3.19 1.95 1.35 1.32 1.13
[25] 1.72 2.53 2.40 2.84 1.38 1.77 1.30 1.94
$disp
[1] 15.80 15.80 10.60 25.60 35.80 22.30 35.80 14.47 13.88 16.56
[11] 16.56 27.38 27.38 27.38 47.00 45.80 43.80 7.67 7.37 6.91
[21] 11.81 31.60 30.20 34.80 39.80 7.70 11.83 9.31 34.90 14.30
[31] 29.90 11.90
$hp
[1] 10.8 10.8 9.1 10.8 17.3 10.3 24.3 6.0 9.3 12.1 12.1 17.8
[13] 17.8 17.8 20.3 21.3 22.8 6.4 5.0 6.3 9.5 14.8 14.8 24.3
[25] 17.3 6.4 8.9 11.1 26.2 17.3 33.3 10.7
从结果可以看到,返回的是一个向量,如果我们只是想得到数据,修改列数据,可以使用这个函数,否则使用transform
函数。
注意到,lapply得到的将结果有些"难看",如果能像原来的数据那样,写成三列会好看许多。一种做法是,转成dataframe格式
as.data.frame(change)
另一种方法是不用lapply函数,而是这用sapply函数。sapply函数是对lapply函数的改写,得到的是dataframe格式数据
> change <- sapply(cars,function(x){(x-2)/10})
> head(change)
mpg cyl hp
[1,] 1.90 0.4 10.8
[2,] 1.90 0.4 10.8
[3,] 2.08 0.2 9.1
[4,] 1.94 0.4 10.8
[5,] 1.67 0.6 17.3
[6,] 1.61 0.4 10.3
tapply 函数
有时候我们想对数据按照一定的标准分组,其中标准是某一列的不同水平值,然后对每组数据进行处理。这个和SQL中的GROUP BY很像。
用法 tapply(X, INDEX, FUN = NULL, ...,)
参数解释,X,FUN函数同上
INDEX 是分类标准所在的列名
注意这里X和INDEX长度相等
例如我们想将具有相同的气缸数的汽车的合并在一起,并得到其mpg的平均值(R中的mean函数),并赋值给bloc变量
> block <- tapply(cars$mpg, cars$cyl, mean)
# 结果
> block
4 6 8
26.66364 19.74286 15.10000
说明:
1.可以将lapply(sapply函数)看做是apply函数的一个子集,因为对所有列或者所有行进行批处理,和对所有数据批处理本质一样。
好啦,关于R中apply系列函数的介绍就到这里,希望能帮助你区分这些易混淆函数。如果还有什么问题,欢迎发表评论。同时也欢迎大家关注我的公众号,有理有数据。