循环生成lm()模型时,公式中的幂无效

时间:2017-09-21 09:56:06

标签: r lm

我正在尝试使用相同的数据制作不同的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)

并将其分配。?

这是My Data Frame

编辑:

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")

1 个答案:

答案 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个图,或者执行您想要的任何其他操作。