使用R做数据处理时,基本不需要用循环,而且效率特别低,所以就衍生出来apply族函数代替循环计算。
apply的家族函数,包括apply, sapply, tapply, mapply, lapply, rapply, vapply, eapply等。我们可以实现对数据的循环、分组、过滤、类型控制等操作。
下面将分别介绍这8个函数的定义和使用方法
1、apply
apply函数是最常用的代替for循环的函数。apply函数可以对矩阵、数据框、数组(二维、多维),按行或列进行循环计算,对子元素进行迭代,并把子元素以参数传递的形式给自定义的FUN函数中,并以返回计算结果。
函数定义:
apply(X, MARGIN, FUN, …)
X: 数组、矩阵、数据框
MARGIN: 按行计算或按按列计算,1表示按行,2表示按列
FUN: 自定义的调用函数
…: 更多参数,可选
2、lapply
lapply函数是一个最基础循环操作函数之一,用来对list、data.frame数据集进行循环,并返回和X长度同样的list结构作为结果集,通过lapply的开头的第一个字母’l’就可以判断返回结果集的类型,
函数定义:
lapply(X, FUN, …)
X:list、data.frame数据
FUN: 自定义的调用函数
…: 更多参数,可选
注意,lapply针对列表向量内的每个元素,并且使用指定函数来对其元素进行处理。返回列表向量,所以出来的结果都是以list形式呈现的。
3、sapply
sapply函数是一个简化版的lapply,sapply增加了2个参数simplify和USE.NAMES,主要就是让输出看起来更友好,返回值为向量,而不是list对象。
sapply(X, FUN, …, simplify=TRUE, USE.NAMES = TRUE)
X:数组、矩阵、数据框
FUN: 自定义的调用函数
…: 更多参数,可选
simplify: 是否数组化,当值array时,输出结果按数组进行分组
USE.NAMES: 如果X为字符串,TRUE设置字符串为数据名,FALSE不设置
注意几个点:
simplify=F:返回值的类型是list,此时与lapply完全相同
simplify=T(默认值):返回值的类型由计算结果定,如果函数返回值长度为1,则sapply将list简化为vector;
如果返回的列表中每个元素的长度都大于1且长度相同,那么sapply将其简化位一个矩阵
4、vapply
vapply类似于sapply,提供了FUN.VALUE参数,用来控制返回值的行名,这样可以让程序更健壮。
函数定义:
vapply(X, FUN, FUN.VALUE, …, USE.NAMES = TRUE)
X:数组、矩阵、数据框
FUN: 自定义的调用函数
FUN.VALUE: 定义返回值的行名row.names
…: 更多参数,可选
USE.NAMES: 如果X为字符串,TRUE设置字符串为数据名,FALSE不设置
通过使用vapply可以直接设置返回值的行名,这样子做其实可以节省一行的代码,让代码看起来更顺畅,当然如果不愿意多记一个函数,那么也可以直接忽略它,只用sapply就够了。
5、 mapply
mapply也是sapply的变形函数,类似多变量的sapply,但是参数定义有些变化。第一参数为自定义的FUN函数,第二个参数’…’可以接收多个数据,作为FUN函数的参数调用。
函数定义:
mapply(FUN, …, MoreArgs = NULL, SIMPLIFY =TRUE, USE.NAMES = TRUE)
FUN: 自定义的调用函数
…: 接收多个数据
MoreArgs: 参数列表
SIMPLIFY: 是否数组化,当值array时,输出结果按数组进行分组
USE.NAMES: 如果X为字符串,TRUE设置字符串为数据名,FALSE不设置
比如,设置两组向量,然后比较对应索引值上那个较小的。
再来个复杂点的:
由于mapply是可以接收多个参数的,所以我们在做数据操作的时候,就不需要把数据先合并为data.frame了,直接一次操作就能计算出结果了。
6、tapply
tapply用于分组的循环计算,通过INDEX参数可以把数据集X进行分组,相当于group by的操作。
函数定义:
tapply(X, INDEX, FUN = NULL, …, simplify = TRUE)
X: 向量
INDEX: 用于分组的索引
FUN: 自定义的调用函数
…: 接收多个数据
simplify : 是否数组化,当值array时,输出结果按数组进行分组
先做一组数据:
现在我想知道按每年每个城市算的销售总数。
所以用于分组的索引有两个,年份和城市,需要显示的量值为销售总数。
(rapply和eapply函数未完待续!)