【问题标题】:perform lm() inside a piped (%>%) flow: Error of invalid term in model formula在管道 (%>%) 流中执行 lm():模型公式中的无效项错误
【发布时间】:2016-07-12 13:47:57
【问题描述】:

我打算按 data.frame 中因子的每个级别执行单独的回归。我曾经可以通过使用 plyr::ddply 来做到这一点。但是,当我尝试使用管道流分析时,我遇到了以下错误。请告知如何克服它,否则我将不得不恢复到 plyr::ddply 等。谢谢。

d = data.frame(
Gender = c("M","F"),
Age = rnorm(20, mean = 40, sd = 3),
Weight = rnorm(20, mean=70, sd=5)
)


fit <- d %>% group_by(Gender) %>%
summarise(
  Intercept = coef(lm(Weight ~ Age))[1],
  Slope = coef(lm(Weight ~ Age))[2]
)

错误:模型公式中的项无效

【问题讨论】:

  • 另外,对于一个复杂的模型,最好只运行一次回归。如何在这样的管道流中完成它?
  • 试试do 而不是summarise
  • 感谢 coffeinjunky 提供有关最佳实践的建议。我已经标记了我喜欢的答案,但两者都工作得很好。

标签: r group-by dplyr lm


【解决方案1】:

更简单的解决方案甚至是使用broombroom::tidy 将模型输出重新排列成漂亮干净的数据帧,您不必手动访问单个系数。如需更多信息,请参阅vignette(broom)

library(dplyr)
library(broom)

fit <- d %>% group_by(Gender) %>% do(data.frame(tidy(lm(Weight ~ Age, data=.))))
fit
Source: local data frame [4 x 6]
Groups: Gender [2]

  Gender        term   estimate  std.error  statistic     p.value
  (fctr)       (chr)      (dbl)      (dbl)      (dbl)       (dbl)
1      F (Intercept) 92.5751034 37.6736331  2.4572916 0.039485169
2      F         Age -0.5132374  0.9098960 -0.5640616 0.588172020
3      M (Intercept) 41.4985927 10.4958042  3.9538269 0.004213341
4      M         Age  0.7346306  0.2691001  2.7299529 0.025847680

在这里,模型输出根据分组变量存储,每个系数存储在单独的行中,您可以轻松地对其进行子集化。

【讨论】:

  • 这里只是一个关于管道的问题。为什么将滚边与传统的function1(function2(function3(x))) 样式混合使用?是不是可以一直通过管道?
  • 好问题。我的理解是do 类似于summarisemutate,你也使用传统的函数调用。例如,你不会写group_by(Gender) %&gt;% mean(var) %&gt;% summarise,而不是group_by(Gender) %&gt;% summarise(mean(var))
【解决方案2】:

使用do 会有所帮助,并且模型将只计算一次:

fit <- d %>% group_by(Gender) %>% 
       do(model = lm(Weight ~ Age, data=.)) %>% 
       mutate(Intercept=coef(model)[1], Slope=coef(model)[2]) %>%
       select(-model)

省略最后一个 select(-model) 以将您的 lm 模型保留在自己的列中。

【讨论】:

    【解决方案3】:

    第一个代码就像写的一样工作(我错过了什么吗?)...

    d = data.frame(
    Gender = c("M","F"),
    Age = rnorm(20, mean = 40, sd = 3),
    Weight = rnorm(20, mean=70, sd=5)
    )
    
    fit <- d %>% group_by(Gender) %>%
    summarise(
      Intercept = coef(lm(Weight ~ Age))[1],
      Slope = coef(lm(Weight ~ Age))[2]
    )
        > fit
    # A tibble: 2 x 3
      Gender Intercept  Slope
      <chr>      <dbl>  <dbl>
    1 F           80.1 -0.322
    2 M           40.6  0.723
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2020-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多