admin管理员组

文章数量:1545226

2024年6月2日发(作者:)

使用apply,sapply,lapply之apply

来源:Pete编译:亮亮

Contents

1测试用的数据

2apply函数

3运行速度

1

1

2

本文介绍如何使用apply,sapply和lapply函数。适用于不熟悉R语言的初学者,文中给出apply家族函数的例子,这些函数广泛

用于各项R代码工作中

1测试用的数据

数据集采用3种方法对比,考查不同方法结果有何不同。我们采用30*3的随机矩阵来开展工作

m<-matrix(data=cbind(rnorm(30,0),rnorm(30,2),rnorm(30,5)),nrow=30,ncol=3)

上述代码用于生成一个矩阵,该矩阵有3列,每列来自于一个正态分布

2apply函数

何时使用apply函数,当我们拥有一个高维的数组或者二维矩阵时,我们需要单独操作某个维度的子集时需要使用它。需要注意一点,

我们再对这类数据操作时要明确每一列的数据类型,否则可能导致数据类型的强制转化,但这些并不是你想要的。当然,

对于熟悉R数据对象的组成原理的读者,可以设计更为精巧的代码避免上述问题。举个例子,我想知道上述m矩阵是否每列的均值分

别为0,2,5呢

apply(m,1,mean)

##[1]1.9980061.880087

##[8]1.5837992.180341

##[15]3.0785462.282524

##[22]2.4915333.513422

##[29]1.5235441.450667

2.738404

2.836111

2.496587

1.738104

2.063448

0.881960

3.012133

1.751636

2.965461

2.247225

2.122539

2.222917

2.447439

1.860909

1.923824

1.414154

2.670303

2.386412

2.479302

1.333947

如果第二个参数我设置为1,发现返回了30个结果,给出的是每一行的均值,并不是我想要的3个数。现在把第二个参数改为2.

apply(m,2,mean)

##[1]0.048293481.815965094.69326994

此外,我们可以定义自己的函数,将其使用在apply函数中。

1

apply(m,2,function(x)length(x[x<0]))

##[1]1610

关于自定义函数,这里注意不要使用表达式,要使用函数将要做的操作封装一下或者提前定义好。此外,为了保持程序的可读性,建

议函数的第一个参数应设置为m对应维度子集的传入参数。

apply使用时,如果每个维度的函数返回值为同样长度,apply会将其整理为一个数组,否则会返回一个列表。这个设计有好处也有坏

处,当我们肯定函数返回的结果长度肯定为同样长度时如上述mean,length类函数,这个设计很好帮我们整理了结果,但是如果返

回的长度不固定,甚至是随机的时候,这个就有点不爽了。

m<-matrix(data=cbind(rnorm(4,0),rnorm(4,sd=2),rnorm(4,sd=5)),nrow=4,ncol=3)

ret<-apply(m,2,function(x)x[x<0])

print(ret)

##

##

##

##

##

##

##

##

[[1]]

[1]-0.3126155-0.5735429-0.2266085

[[2]]

numeric(0)

[[3]]

[1]-3.157289

上述代码将4*3的一个随机正态分布每一列小于0的数据取出来,理论上来讲,这个函数有可能返回长度相同的结果,大家可以试

试,是不是某次出现了不是列表的结果。

3运行速度

library(rbenchmark)

m<-matrix(data=rnorm(10^6*3),nrow=10^6)

rowmean1<-function(m){

}

benchmark()

ret<-apply(m,2,function(x)x[x<0])

print(ret)

总结看来,一般而言,需要对数组或者矩阵的行列使用函数时,我们可采用apply函数。另外,需要知道的是我们完全可以使用for

等循环语句来替代apply函数的功能,速度可能会更快,在此我们不做进一步的讨论。

2

本文标签: 函数矩阵使用数据需要