当对数据进行处理的时候,可能需要单独对某一水平的数据进行处理,这时需要使用split()函数。
> str(split) #列出函数的参数列表
function(x, f, drop=FALSE, ...)
> x <- c(rnorm(10), runif(10),rnorm(10,1))
> f <- gl(3, 10)
> split(x,f)
$`1`
[1] -0.68283668 -0.72841272 0.99720259 -1.10786179 -1.23341727 -0.84170453
[7] 0.30349491 0.01993665 0.30435412 -0.17732936
$`2`
[1] 0.329310104 0.460121336 0.007198808 0.698278960 0.806942514 0.496464276
[7] 0.586641019 0.926427904 0.084612117 0.266162270
$`3`
[1] 2.8339886 -0.4827860 0.8028158 1.4590800 3.0353226 1.5399591
[7] 0.8244989 1.0709710 1.6505017 2.1475552
例子二:
> library(MASS)
> split(Cars93$MPG.city,Cars93$Origin)
$USA
[1] 22 19 16 19 16 16 25 25 19 21 18 15 17 17 20 23 20 29 23 22 17 21 18 29
[25] 20 31 23 22 22 24 15 21 18 17 18 23 19 24 23 18 19 23 31 23 19 19 19 28
$`non-USA`
[1] 25 18 20 19 22 46 30 24 42 24 29 22 26 20 17 18 18 29 28 26 18 17 20 19
[25] 29 18 29 24 17 21 20 33 25 23 39 32 25 22 18 25 17 21 18 21 20
> str(lapply)
function (X, FUN, ...)
“l”代表list,输出为列表,并将指定的操作应用于列表中的所有元素
> str(sapply)
function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
“s”代表simplify,“简化”的意思,与lapply()不同的是,sapply()将对结果进行简化,简化为向量或者矩阵。具体来说,如果apply的结果是一个所有元素长度都为1的list,sapply()会将结果转换为vector;如果apply的结果是一个所有元素长度都相等且大于1的list,sapply()会将结果转换为matrix;如果sapply()无法判断简化规则,则不对结果进行简化,返回list,此时得到的结果和lapply()相同。
> str(apply)
function (X, MARGIN, FUN, ...)
其中:
X是一个矩阵,MARGIN为一个向量(表示要将函数FUN应用到X的行还是列),若为1表示取行,为2表示取列,为c(1,2)表示行、列都计算,FUN为具体函数。
> ma <- matrix(c(1:4, 1, 6:8), nrow = 2)
> ma
[,1] [,2] [,3] [,4]
[1,] 1 3 1 7
[2,] 2 4 6 8
> apply(ma, c(1,2), sum)
[,1] [,2] [,3] [,4]
[1,] 1 3 1 7
[2,] 2 4 6 8
> apply(ma, 1, sum)
[1] 12 20
> apply(ma, 2, sum)
[1] 3 7 7 15
> str(tapply)
function (X, INDEX, FUN = NULL, ..., simplify = TRUE)
其中X通常是一向量;INDEX是一个list对象,且该list中的每一个元素都是与X有同样长度的因子;FUN是需要计算的函数;simplify是逻辑变量,若取值为TRUE(默认值),且函数FUN的计算结果总是为一个标量值,那么函数tapply返回一个数组;若取值为FALSE,则函数tapply的返回值为一个list对象。需要注意的是,当第二个参数INDEX不是因子时,函数 tapply() 同样有效,因为必要时 R 会用 as.factor()把参数强制转换成因子。
> fac <- factor(rep(1:3, length = 17), levels = 1:5)
> fac
[1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2
Levels: 1 2 3 4 5
> tapply(1:17, fac, sum)
1 2 3 4 5
51 57 45 NA NA
> tapply(1:17, fac, length)
1 2 3 4 5
6 6 5 NA NA
有时候需要将函数应用于数据框中的行组。
> a
性别 姓名 分数
1 F a 90
2 F b 85
3 M c 70
4 F d 94
5 M e 60
> by(a,a$性别,summary)
a$性别: F
性别 姓名 分数
F:3 a:1 Min. :85.00
M:0 b:1 1st Qu.:87.50
c:0 Median :90.00
d:1 Mean :89.67
e:0 3rd Qu.:92.00
Max. :94.00
-------------------------------------------
a$性别: M
性别 姓名 分数
F:0 a:0 Min. :60.0
M:2 b:0 1st Qu.:62.5
c:1 Median :65.0
d:0 Mean :65.0
e:1 3rd Qu.:67.5
Max. :70.0
该数据包含一个因子来识别每个记录的性别,所以by可以根据性别将数组分为两组,并且对每组分别调用summary函数。结果为两个汇总,一个是关于男性的,一个是关于女性的。
mappl可以看成是sapply的多变量版本,其用法是:
> str(mapply)
function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRU
将FUN依次应用到每一个参数的第一个元素,第二个元素,第三个…,其中MoreArgs表示函数的参数列表
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