时间: 2018-07-18(学习) 2018-07-22(学习记录)
教程:慕课网 《R语言基础》 讲师:Angelayuan
补充内容: R语言常用函数总结大全、gl()函数
学习内容:课程第四章:重要函数的使用
重要函数
1.lapply & sapply
如:
str()函数,structure,紧凑地显示对象内部结构,即对象里有什么。
> str(lapply)
function (X, FUN, ...)
> x <- list(a=1:10, b=c(11,21,31,41,51))
> x
$`a`
[1] 1 2 3 4 5 6 7 8 9 10
$b
[1] 11 21 31 41 51
> lapply(x,mean) # 对列表x中的每个元素求平均
$`a`
[1] 5.5
$b
[1] 31
> class(lapply(x,mean))
[1] "list"
可以看出,lapply()函数返回的对象类型为列表。
> x1 <- 1:4 # runif 默认从(0,1)中抽取
> runif(5)
[1] 0.88503752 0.06881155 0.38453875 0.54453272 0.36140365
> lapply(x1, runif)
[[1]]
[1] 0.4489252
[[2]]
[1] 0.4759847 0.4693249
[[3]]
[1] 0.9319213 0.8022253 0.8239708
[[4]]
[1] 0.60829270 0.59905232 0.07741152 0.83186815
> class(lapply(x1, runif))
[1] "list"
可以看出,该程序的实质是对x1中的每一个元素使用runif函数,runif函数中的参数即为x1中的元素内容。返回的对象是一个列表。
> lapply(x1, runif,min=0,max=100)
[[1]]
[1] 77.53334
[[2]]
[1] 19.071435 5.407963
[[3]]
[1] 75.00840 89.83947 19.51815
[[4]]
[1] 66.83073 92.35758 42.35655 30.18025
对x1使用runif函数,”min=0,max=100”作用于runif函数,意思为,使抽取的最小值为0,最大值为100。
> x2 <- list(a=matrix(1:6,2,3),b=matrix(4:7,2,2))
> x2
$`a`
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
$b
[,1] [,2]
[1,] 4 6
[2,] 5 7
> lapply(x2,function(m) m[1,])
$`a`
[1] 1 3 5
$b
[1] 4 6
对x2使用function(m)函数,function(m)函数的作用是抽取m的矩阵的第一行,格式为lapply(对象,函数名 函数内容)。
> sapply(x,mean)
a b
5.5 31.0
> class(sapply(x,mean))
[1] "numeric"
可以看出,sapply函数与lapply的作用基本一致,但所得结果与lapply函数结果相比较为简单。
2.apply
apply函数是对数组对象沿着其某一维度进行数据处理的函数,其格式为:apply(数组/数组名,维度,函数/函数名)。
如:
> x <- matrix(1:16,4,4)
> x
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
> apply(x,2,mean) # 对矩阵x的列求平均
[1] 2.5 6.5 10.5 14.5
> apply(x,1,sum) # 对矩阵x的行求和
[1] 28 32 36 40
> class(apply(x,2,mean))
[1] "numeric"
可以看出,apply函数返回的对象是数值型。矩阵的第1个维度为行,第2个维度为列。
rowSums函数、rowMeans函数、colSums函数和colMeans函数是对矩阵进行求平均,求和的函数,作用分别为:对行求和、对行求平均、对列求和、对列求平均。例:
> rowSums(x)
[1] 28 32 36 40
> rowMeans(x)
[1] 7 8 9 10
> colSums(x)
[1] 10 26 42 58
> colMeans(x)
[1] 2.5 6.5 10.5 14.5
> x1 <- matrix(rnorm(100),10,10)
rnorm(100) :从正态总体中抽取100个数。
> x2 <- as.vector(x1)
将x1转化为一个向量,R默认按先列后行的顺序,如果想要按行转化,应输入x2 <-
as.vector(t(x1))[-length(x1)]。
> quantile(x1)
0% 25% 50% 75% 100%
-2.52188938 -0.75854793 0.01278413 0.50218606 2.53157675
> quantile(x2)
0% 25% 50% 75% 100%
-2.52188938 -0.76862008 -0.03151691 0.51595128 2.53157675
可以看出,直接对一个矩阵使用quantile函数,其实质就是对矩阵中所有元素求百分位数,如果想要对每一行或列分别求百分位数,需要使用apply函数。
对x1的每行分别求25%分位点和75%分位点:
> apply(x1,1,quantile,probs=c(0.25,0.75))
[,1] [,2] [,3] [,4] [,5] [,6]
25% -0.7858875 -0.2201546 -0.6949031 -0.5816118 -0.8659978 -0.8314179
75% 0.1181953 0.3378439 0.4806605 0.5125266 0.3238839 0.4293929
[,7] [,8] [,9] [,10]
25% -1.0360972 -0.5325346 -0.8300560 -0.6952302
75% 0.3289841 1.3373911 0.8246093 1.1712271
> class(apply(x1,1,quantile,probs=c(0.25,0.75)))
[1] "matrix"
> x2 <- array(rnorm(2*3*4),c(2,3,4))
> apply(x2,c(1,2),mean)
[,1] [,2] [,3]
[1,] -0.1303495 -0.15920508 -0.3258256
[2,] -0.4381158 -0.03596368 -0.1235411
> apply(x2,c(1,3),mean)
[,1] [,2] [,3] [,4]
[1,] 0.1140517 0.6003327 -0.15505303 -1.3798382
[2,] -0.7958814 0.1819626 0.07241478 -0.2553234
> apply(x2,c(2,3),mean)
[,1] [,2] [,3] [,4]
[1,] -0.005381797 0.63799949 -0.5805872 -1.1889610
[2,] -0.832683878 0.54533972 0.7107023 -0.8136957
[3,] -0.184678873 -0.00989629 -0.2540725 -0.4500857
3.mapply
mapply是lapply的多元版本,格式为:mapply(函数/函数名,数据,函数相关的参数)。
如:
> list(rep(1,4),rep(2,3),rep(3,2),rep(4,1))
[[1]]
[1] 1 1 1 1
[[2]]
[1] 2 2 2
[[3]]
[1] 3 3
[[4]]
[1] 4
> mapply(rep,1:4,4:1)
[[1]]
[1] 1 1 1 1
[[2]]
[1] 2 2 2
[[3]]
[1] 3 3
[[4]]
[1] 4
可以看出,使用该程序生成列表与直接使用list函数套用rep函数返回的结果是一样的,mapply函数中第一个参数是 rep函数,第二个参数是rep函数的第一个参数,即返回对象的数据内容,第三个参数是rep函数的第二个参数,即重复次数。
建立一个函数,函数名为s,有三个参数,内容是从随机总体中抽取n个数,函数的第一个参数是抽取的数据的数量n,第二、三个参数分别是总体的均值和方差:
> s <- function(n, mean, std)
{
rnorm(n, mean, std)
}
> s(4,0,10)
[1] 6.187130 12.654355 6.864007 -5.914964
> mapply(s,1:5,5:1,2)
[[1]]
[1] 4.391382
[[2]]
[1] 6.527374 5.407532
[[3]]
[1] 3.110394 2.861490 1.062697
[[4]]
[1] 1.0589855 0.4850307 1.8892080 2.5943264
[[5]]
[1] 1.4702287 -0.6490873 3.1964053 3.4455908 2.3174738
> class(mapply(s,1:5,5:1,2))
[1] "list"
可以看出,上述程序的作用是生成一个列表,第一个元素是从均值为1,标准差为2的随机总体中抽取1个数,第二个元素是从均值为2,标准差为2的随机总体中抽取2个数。
> list(s(1,5,2),s(2,4,2),s(3,3,2),s(4,2,2),s(5,1,2))
[[1]]
[1] 2.974112
[[2]]
[1] 7.391563 2.021349
[[3]]
[1] 1.011845 5.978735 5.310789
[[4]]
[1] 4.662467 1.260659 3.953015 3.240760
[[5]]
[1] 3.8650932 -0.4452322 1.4689271 0.8915785 0.2668686
4.tapply
tapply函数对向量的子集进行操作,格式为:tapply(向量,因子/因子列表,函数/函数名)。
如:
> x <- c(rnorm(5),runif(5),rnorm(5,1))
> x
[1] 0.59968952 -0.43799554 -1.88220634 -0.01000788 -1.40232262 0.21686806
[7] 0.67216713 0.87636971 0.81726776 0.16794590 0.67250517 0.80001548
[13] -0.11893751 1.80148422 1.95975380
x为一个向量,其中前五个数来自于正态分布,中间五个来自于均匀分布,最后五个来自于均值为1,标准差为0的正态分布
按级别对x进行求均值,x的级别与f中各级别位置一一对应,即每5个数为一个级别,gl函数的具体用法在本文附录部分有补充。例:
> f <- gl(3,5) # 生成三个级别,每个级别5个数
> f
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
Levels: 1 2 3
> class(f)
[1] "factor"
> tapply(x,f,mean)
1 2 3
-0.6265686 0.5501237 1.0229642
> tapply(x,f,mean,simplify = FALSE)
$`1`
[1] -0.6265686
$`2`
[1] 0.5501237
$`3`
[1] 1.022964
tapply函数默认生成紧凑形式,在函数中添加参数”simplify = FALSE”可以得到一个没有化简的列表。
> class(tapply(x,f,mean))
[1] "array"
> class(tapply(x,f,mean,simplify = FALSE))
[1] "array"
可以看出,不管是不是紧凑格式,tapply函数生成的均为数组。
5.分类(split函数)
split函数根据因子或因子列表将向量或其他对象分组,通常用与lapply函数一起使用,格式为split(向量/列表/数据框,因子/因子列表)。
如:
> x <- c(rnorm(5),runif(5),rnorm(5,1))
> x
[1] 1