apply族功能强大,实用,可以代替很多循环语句,先简单介绍apply和tapply函数。
一、apply()函数
apply函数可将一个任意函数“应用”到矩阵、数组、数据框的任何维度上。使用格式如下:
apply(x, MARGIN, FUN, ...)
其中x为数据对象,MARGIN是维度的下标,FUN是由你指定的函数,而...则包括了任何想传递给FUN的参数。在矩阵或数据框中, MARGIN=1表示行, MARGIN=2表示列。
示例如下:
set.seed(100)
mydata <- matrix(rnorm(30), nrow=6) #生成随机数
mydata
[,1] [,2] [,3] [,4] [,5] [1,] -0.50219235 -0.58179068 -0.20163395 -0.9138142 -0.8143791 [2,] 0.13153117 0.71453271 0.73984050 2.3102968 -0.4384506 [3,] -0.07891709 -0.82525943 0.12337950 -0.4380900 -0.7202216 [4,] 0.88678481 -0.35986213 -0.02931671 0.7640606 0.2309445 [5,] 0.11697127 0.08988614 -0.38885425 0.2619613 -1.1577295 [6,] 0.31863009 0.09627446 0.51085626 0.7734046 0.2470760
利用apply求均值
apply(mydata, 2, mean)
[1] 0.1454680 -0.1443698 0.1257119 0.4596365 -0.4421267
apply(mydata, 2, mean, trim=0.2) #去掉端值
[1] 0.1220539 -0.1888731 0.1008213 0.3403341 -0.4355267
注:FUN可为任意R函数,这也包括你自行编写的函数。
二、tapply()函数
tapply()函数可根据因子、向量和要计算的函数计算,使用格式如下:
tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)
其中X通常是一向量;INDEX是一个list对象,且该list中的每一个元素都是与X有同样长度的因子;FUN是需要计算的函数;simplify是逻辑变量,若取值为TRUE(默认值),且函数FUN的计算结果总是为一个标量值,那么函数tapply返回一个数组;若取值为FALSE,则函数tapply的返回值为一个list对象。
示例如下:
Student <- c("John Davis", "Angela Williams", "Bullwinkle Moose",
"David Jones", "Janice Markhammer", "Cheryl Cushing",
"Reuven Ytzrhak", "Greg Knox", "Joel England",
"Mary Rayburn")
Math <- c(502, 600, 412, 358, 495, 512, 410, 625, 573, 522)
English <- c(25, 22, 18, 15, 20, 28, 15, 30, 27, 18)
roster <- data.frame(Student, Math, English,stringsAsFactors=FALSE)
roster$grade[roster$Math <= 500] <- "A"
roster$grade[roster$Math > 500] <- "B"
roster
Student Math English grade
John Davis 502 25 B
Angela Williams 600 22 B
Bullwinkle Moose 412 18 A
David Jones 358 15 A
Janice Markhammer 495 20 A
Cheryl Cushing 512 28 B
Reuven Ytzrhak 410 15 A
Greg Knox 625 30 B
Joel England 573 27 B
Mary Rayburn 522 18 B
1)应用前面的apply求数学和英语的平均分
apply(roster[,c(2,3)],2,mean)
Math English
500.9 21.8
2)当需要分组计算时候,使用tapply函数
tapply(roster[,"English"], roster[,"grade"], mean)
A B
17 25
注:当index不是因子时,可以用as.factor()把参数强制转换成因子
3)aggregate函数同样可以得到类似的结果:
aggregate(x=roster[c('English')], by = list(roster$grade), FUN=mean)
4)实现类似excel的透视表功能
attach(roster)
tapply(English,list(Student,grade),mean)
A B
Angela Williams NA 22
Bullwinkle Moose 18 NA
Cheryl Cushing NA 28
David Jones 15 NA
Greg Knox NA 30
Janice Markhammer 20 NA
Joel England NA 27
John Davis NA 25
Mary Rayburn NA 18
Reuven Ytzrhak 15 NA
以上,apply,tapply可以省去很多循环的分析,其他apply族函数,待续。。。