R语言中有几个经常使用的函数,能够按组对数据进行处理,apply, lapply, sapply, tapply, mapply,等。这几个函数功能有些相似,下面介绍下这几个函数的用法。app
这是对一个Matrix或者Array进行某个维度的运算。其格式是:函数
Apply(数据,维度Index,运算函数,函数的参数)字符串
对于Matrix来讲,其维度值为2,第二个参数维度Index中,1表示按行运算,2表示按列运算。下面举一个例子:io
m<-matrix(1:6,2,3)function
构建一个简单的2行3列的矩阵,内容为:class
[,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6
若是咱们要计算每一行的sum值,那么咱们能够写为:
apply(m,1,sum)
[1] 9 12
若是要计算每一列的mean值,那么改成:
apply(m,2,mean)
[1] 1.5 3.5 5.5
假如某个值为NA,那么要忽略NA值,进行每一行的SUM怎么办呢?
m[2,2]<-NA
[,1] [,2] [,3] [1,] 1 3 5 [2,] 2 NA 6
apply(m,1,sum) [1] 9 NA
自己sum函数有一个参数na.rm,咱们能够将这个参数带人到apply函数中,做为第4个参数:
apply(m,1,sum,na.rm=TRUE) [1] 9 8
须要注意的是若是是Data Frame,那么系统会将其转为Matrix,若是全部Column不是数字类型或者类型不一致,致使转换失败,那么apply是运算不出任何一列的结果的。
前面说到apply是对于matrix和array的,针对list,咱们可使用lapply函数。该函数接收list,返回的结果也是一个list。其调用以下:
Apply(数据,运算函数,函数的参数)
对于Data Frame来讲,若是不一样的列有不一样的数据类型,不能转换成Matrix,可是却能够转换成List,而后使用lapply函数。
咱们创建一个学生名字,年龄和成绩的Data Frame,而后统计平均年龄和平均成绩,因为name列不是数值类型,因此没法算平均值,因此咱们能够对非数值的数据只取count数量。这里就须要用到自定义函数。
函数能够是匿名函数,也能够是以前定义好的函数,因为这里逻辑简单,咱们能够用匿名函数解决。
s<-data.frame(name=c("Devin","Edward","Lulu"),age=c(30,33,29),score=c(95,99,90))匿名函数
name age score 1 Devin 30 95 2 Edward 33 99 3 Lulu 29 90
lapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}})List
$name [1] 3 $age [1] 30.66667 $score [1] 94.66667
咱们能够看到返回了一个List的结果,里面包含3个项,每一个项是函数执行的结果。lapply返回的结果和传入的List的结构相同,传入多少个Item,返回的也是多少个Item。
Sapply函数和Lapply函数很相似,也是对List进行处理,只是在返回结果上,Sapply会根据结果的数据类型和结构,从新构建一个合理的数据类型返回。调用格式以下:
Apply(数据,运算函数,函数的参数,simplify = TRUE, USE.NAMES = TRUE)
对于其中的simplify参数,就是指明是否对返回的结果集从新组织,若是为FALSE,那么就至关于lapply了。USE.NAMES是对字符串数据处理时,是否使用字符串做为命名的。
仍是上面的例子,只是把lapply换成sapply:
sapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}}) name age score 3.00000 30.66667 94.66667
咱们能够看到结果集变成了一个数字向量,而不是List了。
这是对多个数据(multivariate)进行sapply处理,只是调用是参数位置有所变化,先把函数放前面:
mapply(运算函数,函数的参数,第一个传入参数,第二个数据…,SIMPLIFY = TRUE,USE.NAMES = TRUE)
好比咱们自定义一个函数m3,接受3个数值参数,而后将3个数字相乘返回结果:
m3<-function(a,b,c){a*b*c}
而后咱们构建3个向量,他们具备相同的长度:
a<-1:5
b<-2:6
c<-5:1map
如今咱们要求a,b,c中的对应各位数进行m3函数的运算,也就是把a,b,c的第一个数作运算,而后把a,b,c的第二个数作运算,而后第三个数~~~这时候就用mapply很方便:数据类型
mapply(m3,a,b,c) [1] 10 24 36 40 30
OK,就这么简单,实现了对应的各位元素的运算。
前面介绍的几个apply函数都是对总体数据进行处理,而tapply是对向量中的数据进行分组处理。先看看tapply函数的调用格式:
tapply(向量数据,分组标识,运算函数,函数的参数,simplify = TRUE)
咱们以一个学生数据的Data Frame为例来说解tapply函数,先构建一个新的学生数据,包含name,age,score,class,gender:
s<-data.frame(name=c("Devin","Edward","Lulu","Jeneen"),age=c(30,33,29,32),score=c(95,99,90,88),class=c(1,2,1,2),gender=c("M","M","F","F"))
name age score class gender 1 Devin 30 95 1 M 2 Edward 33 99 2 M 3 Lulu 29 90 1 F 4 Jeneen 32 88 2 F
若是咱们要计算每一个班的平均成绩,那么使用tapply的方法是:
tapply(s$score,s$class,mean) 1 2 92.5 93.5
若是改成按gender算平均成绩,那么就是:
tapply(s$score,s$gender,mean) F M 89 97
若是同时按class和gender来看呢?这里就须要把两个向量构建成list做为第二个参数传入:
tapply(s$score,list(s$class,s$gender),mean) F M 1 90 95 2 88 99