我知道这是一个愚蠢的新手问题,但我已经尝试了很长一段时间,需要一些输入。基本上,我正在尝试学习如何使用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
每次只对一列调用它的函数。你需要的是mapply
或Map
。
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)
但是mapply
和Map
允许任意数量的列表/向量,所以例如
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
更容易阅读。