【发布时间】:2015-08-19 12:18:55
【问题描述】:
我正在使用 R 中 INLA 包的一组结果。这些结果存储在具有有意义名称的对象中,因此我可以在当前环境中拥有例如 model_a、model_b... .对于这些模型中的每一个,我都想做几个处理任务,包括将数据提取到单独的数据框,然后可以将其用于合并到空间数据以创建地图等。
转向更简单、可重现的示例,让我们假设两个结果
ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2, 10, 20, labels = c("Ctl","Trt"))
weight <- c(ctl, trt)
model_a <- lm(weight ~ group)
model_b <- lm(weight ~ group - 1)
我可以处理单个模型的步骤,例如:
model_a_sum <- data.frame(var = character(1), model_a_value = numeric(1))
model_a_sum$var <- "Intercept"
model_a_sum$model_a_value <- model_a$coefficients[1]
png("model_a_plot.png")
plot(model_a, las = 1)
dev.off()
现在,我想为每个模型重用这段代码,本质上是根据我使用的模型构建正确的名称。我比 R 人更 Stata,并且在 Stata 内部,使用名称的存根(model_a,甚至仅a..)并构建将实现所有步骤的foreach 循环将是一项微不足道的任务,为每个模型调整名称。
在 R 中,for 循环在整个互联网上都受到抨击,所以我认为我不应该尝试涉足以下领域:
models <- c("model_a", "model_b", "model_c")
for (model in models) {
...
}
对于这种情况,更好的解决方案是什么?
更新 1:由于 cmets 建议 for 可能确实是一个选项,我试图将所有任务放入一个循环中。到目前为止,我设法使用assign 正确命名数据框,并使用get 以正确的名称绘制正确的数据:
models <- c("model_a", "model_b")
for (i in 1:length(models)) {
# create df
name.df <- paste0(models[i], "_sum")
assign(name.df, data.frame(var = character(1), value = numeric(1)))
# replace variables of df with results from the model
# plot and save
name.plot <- paste0(models[i], "_plot.png")
png(name.plot)
plot(get(models[i]), which = 1, las = 1)
dev.off()
}
这是合理的方法吗?有更好的解决方案吗?
我无法解决的一件事是根据模型命名 df 的第二个变量(即model_a_value 而不是当前的value。任何想法如何解决这个问题?
【问题讨论】:
-
我认为
for解决方案在这种情况下是一个不错的选择,您的函数将像您一样生成要写入磁盘的文件。使用对象名称作为变量,然后for (i in 1:length(models)) your.function(models[i])为您的流程创建一个函数。 -
我认为 for 循环完全适合这种任务,但如果你有大量的模型对象要处理,你可能会从并行化中受益——在这种情况下,我会使用
foreach包。 -
"在 R 中,for 循环在整个互联网上都受到了抨击 " 互联网上的一切都永远存在,R 中的 for 循环 很慢,现在已经不是这样了,所以没有有理由在选择它们时避免使用它们。如果您可以使用“矢量化”(即仅使用可以将矢量作为入口的函数)方式,请避免使用它们,因为处理已针对此进行了优化。
-
另一种选择是列出您的模型公式;然后制作单独的函数a)估计模型并提取系数和b)估计然后绘制模型;然后分别使用
lapply()和rapply()将这些函数应用于模型公式列表。 -
@hoffmanc @Tensibai @ulfelder 感谢所有 cmets。将尝试追求
for解决方案。