r语言 - 如何对矩阵或数据框的列使用apply(或sapply)作为函数参数



我知道这是一个愚蠢的新手问题,但我已经尝试了很长一段时间,需要一些输入。基本上,我正在尝试学习如何使用apply家族来省略for循环,特别是如何设置调用,以便矩阵的列作为函数的参数。我将使用对rbinom函数的简单调用作为示例。

示例:这个for循环工作得很好。数据是一组整数和一组概率

success <- rep(-1, times=10)                             # initialize result var
num <- sample.int(20, 10)                                # get 10 random integers 
p <- runif(10)                                           # get 10 random probabilities
for (i in 1:10) {
success[i]= rbinom(n=1, size=num[i],prob=p[i])          # number successes in 1 trial
} 

但是如何对apply族做同样的事情呢?我首先把数据放入一个矩阵的两列,认为这是一个正确的开始。然而,以下不工作,显然是由于我的不理解如何设置调用来应用。

myData <- matrix(nrow=10, ncol=2)
myData[,1] <- num
myData[,2] <- p
success <- apply(myData, rbinom, n=1, size=myData[,1], prob=myData[,2])

任何提示都非常感谢!我要从Fortran转到R,并尝试移植许多加载了DO循环的代码,所以我真的需要弄清楚这个。

lapply,sapply,apply每次只处理一个向量/列表。也就是说,apply每次只对一列调用它的函数。你需要的是mapplyMap

myData <- matrix(nrow=10, ncol=2)
myData[,1] <- num
myData[,2] <- p
mapply(rbinom, n = 1, myData[,1], myData[,2])
#  [1]  5  4 11  8  3  3 17  8  0 11

就像lapply返回一个列表一样,Map也是;类似地,就像sapply一样,如果所有返回值都兼容,mapply将返回一个向量或数组,否则它也返回一个list

这些调用是等价的:

sapply(1:3, function(z) z + 1)
mapply(function(z) z + 1, 1:3)

但是mapplyMap允许任意数量的列表/向量,所以例如

func <- function(X,Y,Z) X^2+2*Y-Z
Map(func, 1:9, 11:19, 21:29)
## effectively the same as
list(
func(1, 11, 21),
func(2, 12, 22),
func(3, 13, 33),
...,
func(9, 19, 29)
)

对于您的数据,sapply的等效调用将是

sapply(seq_len(nrow(myData)), function(ind) {
rbinom(n = 1, size = myData[ind,1], prob = myData[ind,2])
})

虽然我个人觉得mapply更容易阅读。

最新更新