本周主要介绍了5个apply函数以及split的用法:
-lapply
-sapply
-apply
-tapply
-mapply
-split  

lapply

  输入一个列表,通过循环后输出一个列表。原列表的名称会被保留。

str(lapply)
## function (X, FUN, ...)
    x       表示输入一个列表
    FUN     表示输入一个循环的函数
    ...     表示对各个元素作用的参数
#这里对list里的每个元素:a和b都进行了取均值操作。
x<-list(a=1:5, b=rnorm(10))
lapply(x,mean)
## $a
## [1] 3
## 
## $b
## [1] 0.3408504

  使用runif(n)函数可以生成n个[0,1]均匀分布的数字

#这里对list里的每个元素(矩阵):a和b都进行了自定义的函数的操作(取第一列)。从中我们发现,对于loop function而言,可以自定义函数来丰富用途。
x<-list(a=matrix(1:4, nrow = 2, ncol = 2),b=matrix(1:6, nrow = 3, ncol = 2))
x
## $a
##      [,1] [,2]
## [1,]    1    3
## [2,]    2    4
## 
## $b
##      [,1] [,2]
## [1,]    1    4
## [2,]    2    5
## [3,]    3    6
lapply(x,function(fc) fc[,1])
## $a
## [1] 1 2
## 
## $b
## [1] 1 2 3

slapply

  简化版的lapply,输出的类型不是列表。

lapply输出 sapply的输出
列表每个列只有一个元素 返回向量
列表每个列有多个元素 返回矩阵
#对于同一个列表,lapply和sapply的输出结果的可视化效果是不同的。
x<-list(a=1:5, b=rnorm(10))
lapply(x,mean)
## $a
## [1] 3
## 
## $b
## [1] 0.1204788
sapply(x,mean)
##         a         b 
## 3.0000000 0.1204788

apply

  作用于数组Array

 str(apply)
## function (X, MARGIN, FUN, ...)
    x       表示一个数组活矩阵
    margin  表示需要被保留的行/列(用向量表示)
    fun     表示循环的函数
    ...     表示循环的其他参数变量
#生成一个20*10的矩阵,返回行/列的均值(1表示行,2表示列)
x<-matrix(rnorm(200),20,10)
apply(x,2,mean)
##  [1] -0.06188239 -0.03269108  0.58289229 -0.36218301 -0.03836910
##  [6] -0.02537240  0.46658706 -0.17852356 -0.15340693 -0.07022349
apply(x,1,mean)
##  [1] -0.29701778 -0.14006171 -0.43917206  0.29984874 -0.06061634
##  [6]  0.80750995 -0.11379374  0.72217569  0.03984844  0.18639416
## [11] -0.30038746  0.38263315 -0.22407108  0.26671167  0.26499031
## [16] -0.29352288 -0.15593159  0.21355030 -0.50629262 -0.39914037

  通常情况下,矩阵的行列的均值及和可以用以下函数来代替:

rowSums=apply(x,1,sum)
rowMeans=apply(x,1,mean)
colSums=apply(x,2,sum)
colMeans=apply(x,2,mean)

  再看一个例子:

#这里返回的是x矩阵列元素的25%和75%分位点
x<-matrix(rnorm(200),20,10)
apply(x,2,quantile,probs=c(0.25,0.75))
##           [,1]       [,2]       [,3]       [,4]       [,5]       [,6]
## 25% -0.9424618 -0.9698283 -0.5705675 -0.1404938 -0.2693255 -0.6847354
## 75%  0.3759125  0.5900999  0.4542125  1.1869608  1.3508776  0.5925187
##           [,7]       [,8]       [,9]       [,10]
## 25% -0.3615953 -0.4143352 -0.6975408 -1.12497462
## 75%  0.5297599  0.6186339  0.4515598  0.09709502

mapply

  m表示muti的意思,将函数依次应用每一个参数的每一个元素上。

str(mapply)
## function (FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE)
    fun             作用的函数
    MoreArgs        函数FUN的参数列表
    simplify        输出的结果为列表还是简化输出形式
    use.names       是否保留名称
#在标准差为2的情况下,在均值为1,2,...,5的正态分布函数中,分别取1个2个...5个数。
noise<-function(n,mean,sd){rnorm(n,mean,sd)}
mapply(noise,1:5,1:5,2)
## [[1]]
## [1] -0.7426653
## 
## [[2]]
## [1] 0.8913268 4.1345896
## 
## [[3]]
## [1] 3.3386378 5.2706587 0.2658873
## 
## [[4]]
## [1] 6.728787 5.849955 6.162188 8.584332
## 
## [[5]]
## [1] 5.524032 6.096981 5.827205 5.791165 4.689238
#等同于
list(noise(1, 1, 2), noise(2, 2, 2),
noise(3, 3, 2), noise(4, 4, 2),
noise(5, 5, 2))
## [[1]]
## [1] 0.996337
## 
## [[2]]
## [1] 1.473952 4.966508
## 
## [[3]]
## [1] 2.974292 1.283822 6.818675
## 
## [[4]]
## [1] 2.192741 7.413558 7.487915 4.678593
## 
## [[5]]
## [1] 4.411867 3.475751 1.542282 3.612318 5.994316

tapply

  作用于一个向量或者一个子集上的循环函数。

str(tapply)
## function (X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE)
    x               向量
    INDEX           因子列表(分类的依据)
    FUN             作用的函数
    ...             其他作用的参数
    simplify        简化输出(默认TRUE)
#将求每个因子分组下的均值,x代表向量,f因子表示分组的依据。
x <- c(rnorm(10), runif(10), rnorm(10, 1))
f <- gl(3, 10)
tapply(x, f, mean)
##          1          2          3 
## -0.1252369  0.4973668  0.8715860

split

  split不是一个循环函数,但是常和其他的循环函数放在一起使用。

str(split)
## function (x, f, drop = FALSE, ...)
    x       代表向量/列表/数据帧中的一种类型
    f       因子
    drop    是否不输出空的因子所在的分组(默认FALSE,输出)
#与tapply相似,只是用split函数将x向量按照f的因子分组
x <- c(rnorm(10), runif(10), rnorm(10, 1))
f <- gl(3, 10)
split(x, f)
## $`1`
##  [1] -0.6887626  1.0373056 -0.3518526 -1.3829744  1.4510218  0.5454222
##  [7]  0.1869283  1.4108691  0.2388184 -0.4149929
## 
## $`2`
##  [1] 0.6257186 0.4020127 0.7690439 0.4558853 0.8105415 0.3457467 0.5945598
##  [8] 0.7318233 0.9643959 0.3295082
## 
## $`3`
##  [1]  1.07755769  1.32347784 -0.35257708  1.50591536  2.42150231
##  [6] -0.75350222  0.80560197  1.88319525 -0.07647322  1.18882857
#split函数与lapply函数的结合使用:
lapply(split(x, f), mean)
## $`1`
## [1] 0.2031783
## 
## $`2`
## [1] 0.6029236
## 
## $`3`
## [1] 0.9023526
#采用R自带的空气质量数据集
library(datasets)
#按照月份(因子)进行分割(成一个列表形式的数据结构)
s <- split(airquality, airquality$Month)
#用lapply求列均值的结果返回时一个列表
lapply(s, function(x) colMeans(x[, c("Ozone", "Solar.R", "Wind")]))
## $`5`
##    Ozone  Solar.R     Wind 
##       NA       NA 11.62258 
## 
## $`6`
##     Ozone   Solar.R      Wind 
##        NA 190.16667  10.26667 
## 
## $`7`
##      Ozone    Solar.R       Wind 
##         NA 216.483871   8.941935 
## 
## $`8`
##    Ozone  Solar.R     Wind 
##       NA       NA 8.793548 
## 
## $`9`
##    Ozone  Solar.R     Wind 
##       NA 167.4333  10.1800
#但是用sapply返回的就是数据帧
sapply(s, function(x) colMeans(x[, c("Ozone", "Solar.R", "Wind")]))
##                5         6          7        8        9
## Ozone         NA        NA         NA       NA       NA
## Solar.R       NA 190.16667 216.483871       NA 167.4333
## Wind    11.62258  10.26667   8.941935 8.793548  10.1800
#将缺失值剔除后:
sapply(s, function(x) colMeans(x[, c("Ozone", "Solar.R", "Wind")],na.rm = TRUE))
##                 5         6          7          8         9
## Ozone    23.61538  29.44444  59.115385  59.961538  31.44828
## Solar.R 181.29630 190.16667 216.483871 171.857143 167.43333
## Wind     11.62258  10.26667   8.941935   8.793548  10.18000