gpt4 book ai didi

r - 为什么不使用 for 循环呢?

转载 作者:行者123 更新时间:2023-12-01 16:13:51 25 4
gpt4 key购买 nike

我在网上看到了很多数据科学家关于为什么不建议使用 for 循环的评论。然而,我最近发现自己处于一种使用它很有帮助的情况。我想知道以下过程是否有更好的替代方案(以及为什么替代方案会更好):

我需要运行一系列重复测量方差分析,并以类似于下面看到的可重现示例的方式解决该问题。

[我知道运行多个方差分析模型还存在其他问题,并且此类分析还有其他选项,但现在我只想了解 for 循环的使用]

例如,四个重复测量方差分析模型 - 四个因变量,每个因变量在三个场合进行测量:

set.seed(1976)
code <- seq(1:60)
time <- rep(c(0,1,2), each = 20)
DV1 <- c(rnorm(20, 10, 2), rnorm(20, 10, 2), rnorm(20, 14, 2))
DV2 <- c(rnorm(20, 10, 2), rnorm(20, 10, 2), rnorm(20, 10, 2))
DV3 <- c(rnorm(20, 10, 2), rnorm(20, 10, 2), rnorm(20, 8, 2))
DV4 <- c(rnorm(20, 10, 2), rnorm(20, 10, 2), rnorm(20, 10, 2))
dat <- data.frame(code, time, DV1, DV2, DV3, DV4)

outANOVA <- list()

for (i in names(dat)) {
y <- dat[[i]]
outANOVA[i] <- summary(aov(y ~ factor(time) + Error(factor(code)),
data = dat))
}

outANOVA

最佳答案

你可以这样写,这样更紧凑:

outANOVA <-
lapply(dat,function(y)
summary(aov(y ~ factor(time) + Error(factor(code)),data = dat)))

for 循环不一定比 apply 函数慢,但对于很多人来说它们不太容易阅读。这在某种程度上是一个品味问题。

真正的犯罪是在矢量化函数可用时使用 for 循环。这些向量化函数通常包含用 C 编写的 for 循环,速度要快得多(或调用这样做的函数)。

请注意,在这种情况下,我们还可以避免创建全局变量y,并且我们不必初始化列表outANOVA

另一点,直接来自此相关帖子:For loops in R and computational speed (Glen_b 回答):

For loops in R are not always slower than other approaches, like apply - but there's one huge bugbear - •never grow an array inside a loop

Instead, make your arrays full-size before you loop and then fill them up.

在您的情况下,您正在增长outANOVA,对于大循环,它可能会出现问题。

以下是一个简单示例中不同方法的一些微基准测试:

n <- 100000
microbenchmark::microbenchmark(
preallocated_vec = {x <- vector(length=n); for(i in 1:n) {x[i] <- i^2}},
preallocated_vec2 = {x <- numeric(n); for(i in 1:n) {x[i] <- i^2}},
incremented_vec = {x <- vector(); for(i in 1:n) {x[i] <- i^2}},
preallocated_list = {x <- vector(mode = "list", length = n); for(i in 1:n) {x[i] <- i^2}},
incremented_list = {x <- list(); for(i in 1:n) {x[i] <- i^2}},
sapply = sapply(1:n, function(i) i^2),
lapply = lapply(1:n, function(i) i^2),
times=20)

# Unit: milliseconds
# expr min lq mean median uq max neval
# preallocated_vec 9.784237 10.100880 10.686141 10.367717 10.755598 12.839584 20
# preallocated_vec2 9.953877 10.315044 10.979043 10.514266 11.792158 12.789175 20
# incremented_vec 74.511906 79.318298 81.277439 81.640597 83.344403 85.982590 20
# preallocated_list 10.680134 11.197962 12.382082 11.416352 13.528562 18.620355 20
# incremented_list 196.759920 201.418857 212.716685 203.485940 205.441188 393.522857 20
# sapply 6.557739 6.729191 7.244242 7.063643 7.186044 9.098730 20
# lapply 6.019838 6.298750 6.835941 6.571775 6.844650 8.812273 20

关于r - 为什么不使用 for 循环呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48793273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com