如何在R语言中用apply等函数替代for循环
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在R语言中用apply等函数替代for循环相关的知识,希望对你有一定的参考价值。
参考技术A 函数主体可以是一系列表达式,这些表达式需要用大括号括起来:function(param1,,paramN)expr1exprM讨论函数的定义告诉R软件“用何种方式进行计算”。例如,R软件没有内置计算变异系数的函数,因此你可以定义函数如下:>cvcv(1:10)[1]0.5504819第一行定义了名为cv的函数,第二行引用该函数,以1∶10作为其参数x的值。函数对参数应用函数主体中的表达式sd(x)/mean(x)进行计算并返回结果。定义函数后,我们可以在任何需要函数的地方应用它,例如可以作为lapply函数的第二个参数(参见方法6.2):>cvlapply(lst,cv)函数主体如果包含多行表达式,则需要使用大括号来确定函数内容的起始和结束位置。下面这一函数采用了欧几里德算法计算两个整数的最大公约数:>gcdlapply(lst,function(x)sd(x)/mean(x))由于本书重点不在于介绍R的编程语言,这里不对R函数编程的细微之处进行解释。下面给出几个需要注意的地方:返回值所有函数都有一个返回值,即函数主体最后一个表达式值。你也可以通过return(expr)命令给出函数的返回值。值调用函数参数是“值调用”——如果你改变了函数中的参数值,改变只是局部的,并不会影响该参数所引用的变量值。局部变量你可以简单地通过赋值来创建一个局部变量,函数结束后该局部变量会消失。条件执行R语法中包含if语句,详情可以使用help(Control)命令查看。循环语句R语言中apply系列函数详解
文章目录
R语言的循环效率并不高,所以并不推荐循环以及循环嵌套。为了实现循环功能的情况下,兼顾效率,R语言提供了apply
系列函数,用于对规则的数据进行函数式的迭代处理。
apply
apply
函数作用于两个维度以上的数组或矩阵,其必要的输入参数有三,分别是待处理数据、用于循环的维度、处理函数,示例如下
data <- matrix(c(1:20), 5, 4)
apply(data, 1, mean)
# [1] 8.5 9.5 10.5 11.5 12.5
上述代码的含义是,对data
的第一个维度,执行平均值mean
操作,换言之,对每一行取平均值。data
是5行4列的矩阵,每行取平均值,可得到拥有4个元素的向量。
apply
也支持对多个坐标轴的数据进行操作,仍以data
为例,若想对所有元素取根号,则可以写为下面这样,其结果于sqrt(data)
相同
> apply(data, 1:2, sqrt)
[,1] [,2] [,3] [,4]
[1,] 1.000000 2.449490 3.316625 4.000000
[2,] 1.414214 2.645751 3.464102 4.123106
[3,] 1.732051 2.828427 3.605551 4.242641
[4,] 2.000000 3.000000 3.741657 4.358899
[5,] 2.236068 3.162278 3.872983 4.472136
lapply, sapply, vapply
apply
不能作用于一维数组,lapply
和sapply
补充了这一功能
> arr <- apply(data, 1, mean)
> apply(arr, 1, sqrt)
Error in apply(arr, 1, sqrt) : dim(X)的值必需是正数
> sapply(arr, sqrt)
[1] 2.915476 3.082207 3.240370 3.391165 3.535534
> lapply(arr, sqrt)
[[1]]
[1] 2.915476
[[2]]
[1] 3.082207
[[3]]
[1] 3.24037
[[4]]
[1] 3.391165
[[5]]
[1] 3.535534
从上面代码可知,二者主要区别是返回值,sapply
会根据实际情况调整返回值,其返回逻辑为
- 1个列表->向量
- 多个长度相同的列表->矩阵,
- 多个长度不同的列表->列表
相比之下,vapply
可以更加灵活地选择输出数据类型
> vapply(arr, sqrt, numeric(1))
[1] 2.915476 3.082207 3.240370 3.391165 3.535534
rapply
rapply
可以处理嵌套列表,其与lappy
的区别试一下就知道
> x <- list(1,2,c(1:5))
> sapply(x, sqrt)
[[1]]
[1] 1
[[2]]
[1] 1.414214
[[3]]
[1] 1.000000 1.414214 1.732051 2.000000 2.236068
> rapply(x, sqrt)
[1] 1.000000 1.414214 1.000000 1.414214 1.732051 2.000000 2.236068
换言之,rapply
在执行的过程中,会不断地检查是否存在列表,如果存在列表,就把这个列表打开,其可用参数除了x, fun
之外,还可指定处理的类别classes
,以及处理方法how
,how
可选三个参数
"replace"
直接替换list中原来的元素"list"
新建一个列表,元素类型复合classes则调用FUN"unlist"
相当于对"list"
模式下的结果调用unlist(recursive=TRUE)
tapply
tapply
可对输入数据进行分组操作,下面以鸢尾花数据作为示例,来体验一下tapply
的用法
> tapply(iris$Sepal.Length, iris$Species, mean)
setosa versicolor virginica
5.006 5.936 6.588
iris
提供了三种鸢尾花的长度、宽度等数据,其中iris$Species
为其种类信息。上面代码的含义是,对iris
的长度,按照相同的Species
取平均值。
mapply
mapply
的使用逻辑是,对两组相同维度的数据进行某种函数操作,类似于执行下面的操作
for(i in 1:N)
func(L1[i], L2[i])
下面以两种不同类别的鸢尾花做个示例
L1<-iris[iris$Species=="setosa",]
L2<-iris[iris$Species=="virginica",]
max(L1$Sepal.Length, L2$Sepal.Length)
# 返回值为7.9,计算了所有数据中的最大值
下面通过mapply
,可以发现对每种类别的50组数据进行了以一比对,并选择出了最大值
> mapply(max, L1$Sepal.Length, L2$Sepal.Length)
[1] 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3 6.7 7.2 6.5 6.4 6.8 5.7 5.8
[16] 6.4 6.5 7.7 7.7 6.0 6.9 5.6 7.7 6.3 6.7 7.2 6.2 6.1 6.4 7.2
[31] 7.4 7.9 6.4 6.3 6.1 7.7 6.3 6.4 6.0 6.9 6.7 6.9 5.8 6.8 6.7
[46] 6.7 6.3 6.5 6.2 5.9
以上是关于如何在R语言中用apply等函数替代for循环的主要内容,如果未能解决你的问题,请参考以下文章