我正在尝试使用相同的数据制作不同的lm模型,但通过更改指数来显示更高阶的交互。我试图在for循环中创建它而不是写多行。但是我得到了“公式中的无效力量”错误。
for (m in 1:5){
assign(paste("lm.", m, sep = ""), lm(paste("Response ~ (Factor1+Factor2+Factor3+Factor4+Factor5)^", m, sep = "")))
}
问:导致此问题的原因以及如何解决?
其次,我希望粘贴lm函数(Factor1 + Factor2 + ...)中的因子数量,因为因子数量会发生变化。
由于上述错误,我也无法看到这是否有效。
我试过了:
for (m in 1:n.factors){
# Make a string to paste in lm()
assign(paste("lm.paste.", m, sep = ""), paste("Response ~ (", paste(factors, collapse="+"), ")^", m, sep = ""))
# Paste in string to lm()
assign(paste("lm.", m, sep = ""), lm(lm.paste.1, data=data.df))
}
其中“因子”是包含我的因子串的向量(“因子1”,“因子2”......)。 n.factors是因素的数量。
问:这是正确的做法吗?感觉有点麻烦。
也许有一些方法可以使用
lm(Response ~ ., data = data.df)
并将其分配。?
编辑:
dput(head(data.df, 20))
structure(list(Factor1 = c(-1, 1, -1, 1, -1, 1, -1, 1, -1, 1,
-1, 1, -1, 1, -1, 1, -1, 1, -1, 1), Factor2 = c(-1, -1, 1, 1,
-1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1), Factor3 = c(-1,
-1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1,
-1), Factor4 = c(-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1,
1, 1, 1, 1, -1, -1, -1, -1), Factor5 = c(-1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1), Response = c(680.45,
722.48, 702.14, 666.93, 703.67, 642.14, 692.98, 669.26, 491.58,
475.52, 478.76, 568.23, 444.72, 410.37, 428.51, 491.47, 607.34,
620.8, 610.55, 638.04), Order = c(17, 30, 14, 8, 32, 20, 26,
24, 10, 16, 27, 18, 3, 19, 31, 15, 12, 1, 4, 23)), .Names = c("Factor1",
"Factor2", "Factor3", "Factor4", "Factor5", "Response", "Order"
), row.names = c(NA, 20L), class = "data.frame")
答案 0 :(得分:4)
您的问题很简单,1 lm
中的权力不是可接受的值:
> lm(mpg ~ cyl^1, mtcars)
Error in terms.formula(formula, data = data) : invalid power in formula
如果您将迭代器更改为使用2:5,那么它将运行:
> for (m in 2:5) {lm(paste0("mpg ~ cyl^",m), mtcars);print("ok")}
[1] "ok"
[1] "ok"
[1] "ok"
[1] "ok"
> for (m in 1:5) tryCatch({lm(paste0("mpg ~ cyl^",m), mtcars);print("ok")}, error = function(e) warning(e))
[1] "ok"
[1] "ok"
[1] "ok"
[1] "ok"
Warning message:
In terms.formula(formula, data = data) : invalid power in formula
如果值为1,您可以编写一些返回空字符串的代码,如果值不是1,则可以返回“^ m”,如果必须在^ 1版本中,则将其连接到公式的末尾循环。
要回答您的第二个问题,我强烈建议从不在此类工作中使用assign
。一旦你的lm对象进入全局环境,就很难让他们回来用它们做更多的事情。如果你想将你的m扩展到20,或者如果你想为任何给定的m推广你的代码,那将非常困难。
更好的选择是将lm对象存储在列表中。您可以通过将for循环更改为lapply调用来非常简单地执行此操作:
> results <- lapply(2:5, function(x) lm(paste0("mpg ~ cyl^",x), mtcars))
> str(results)
List of 4
$ :List of 12
...snip...
$ :List of 12
...snip...
$ :List of 12
...snip...
$ :List of 12
...snip...
现在,您可以遍历列表,同时为每个模型执行“某些操作”:
> purrr::map(results, function(x) x$coefficients)
[[1]]
(Intercept) cyl
37.88458 -2.87579
[[2]]
(Intercept) cyl
37.88458 -2.87579
[[3]]
(Intercept) cyl
37.88458 -2.87579
[[4]]
(Intercept) cyl
37.88458 -2.87579
这适用于任何要应用于lm对象列表的函数,任何m,或任何lm对象列表,甚至任何类型对象的列表,例如:
> purrr::map(results, broom::tidy)
[[1]]
term estimate std.error statistic p.value
1 (Intercept) 37.88458 2.0738436 18.267808 8.369155e-18
2 cyl -2.87579 0.3224089 -8.919699 6.112687e-10
[[2]]
term estimate std.error statistic p.value
1 (Intercept) 37.88458 2.0738436 18.267808 8.369155e-18
2 cyl -2.87579 0.3224089 -8.919699 6.112687e-10
[[3]]
term estimate std.error statistic p.value
1 (Intercept) 37.88458 2.0738436 18.267808 8.369155e-18
2 cyl -2.87579 0.3224089 -8.919699 6.112687e-10
[[4]]
term estimate std.error statistic p.value
1 (Intercept) 37.88458 2.0738436 18.267808 8.369155e-18
2 cyl -2.87579 0.3224089 -8.919699 6.112687e-10
现在您有一个数据框列表,其中每个数据框包含一些有关模型的有趣信息。您可以使用purrr::map
依次检查每个数据框中的p值并使用它们执行操作,或创建拟合回归线的4个图,或者执行您想要的任何其他操作。