这个问题主要是为了学习优秀的R编程实践。我想对复制函数中表达式的单个变量的不同输入重复replicate
函数。我可以使用for
循环轻松完成此操作,但我反复听说如果我在R中使用for循环,我做错了。 有没有办法在没有循环的情况下使用不同的输入重复调用replicate
?之后,到目前为止,我有最好的尝试。
循环工作代码:
set.seed(1564) #Birth of Galileo!
x <- rnorm(1000, 15, 3)
y <- 2*x + rnorm(1000, 0, 5)
cor(x, y)
cor.fxn <- function(N, x, y) {
samp.row <- sample(1:1000, N)
cor(x[samp.row], y[samp.row])
}
N.list <- seq(3,20)
cor.list <- rep(NA_real_, length(N.list))
for (N in N.list){
cor.resamp <- replicate(1000, cor.fxn(N, x, y))
cor.list[N-2] <- median(cor.resamp)
}
plot(N.list, cor.list)
没有循环的非功能性最佳尝试:
set.seed(1564) #Birth of Galileo!
x <- rnorm(1000, 15, 3)
y <- 2*x + rnorm(1000, 0, 5)
X <- list(3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
eggs <- lapply(X, replicate, n=1000, expr=cor.fxn, x=x, y=y)
哪个会出错:
Error in FUN(X[[i]], ...) :
unused arguments (x = c(9.17486389116665, 13.6573453081421, 12.2166561575586, 11.3619489970582, 17.9998611075272, 11.1171958860255, 20.4489048239365, 16.8825343591062, 12.9990097472942, 12.5617129892976, 10.9833420846924, 13.7732692244654, 16.9641205588413, 11.1309409503371, 11.7859737745279,...
感谢您的帮助。
答案 0 :(得分:1)
R中的循环速度很慢,但您可能没有听到的另一部分是您应该对您的操作进行矢量化。 * apply系列函数本身并不比for循环快。让我们看看一些基准
# Boiler plate code used for both functions
cor.fxn <- function(N, x, y) {
samp.row <- sample(1:1000, N)
cor(x[samp.row], y[samp.row])
}
set.seed(1564) #Birth of Galileo!
x <- rnorm(1000, 15, 3)
y <- 2*x + rnorm(1000, 0, 5)
N.list <- seq(3,20)
# Using 'for loop'
foo_a = function(....) {cor.list <- rep(NA_real_, length(N.list));
for (N in N.list) {
cor.resamp <- replicate(1000, cor.fxn(N, x, y))
cor.list[N-2] <- median(cor.resamp)
}
}
# Using sapply
foo_b = function(...) sapply(3:20, function(n) median(replicate(1000, cor.fxn(n, x, y))))
microbenchmark(foo_a(), foo_b(), times = 100L)
如上所述,看起来两种方法之间的时间没有区别。
Unit: milliseconds
expr min lq mean median uq max neval
foo_a() 939.7068 1041.964 1140.159 1146.065 1243.540 1367.411 100
foo_b() 936.5962 1045.023 1138.337 1133.074 1239.099 1334.430 100
这个特定的测试用例无法进行矢量化,因为您需要处理1000次运行的中位数。这篇文章的重点是要指出for循环并不比在R中应用族函数差。但是,在可能的情况下,你应该总是在循环/应用解决方案上寻找矢量化解决方案。