R 在管道(%>;%)流中执行lm():模型公式中的无效项错误

R 在管道(%>;%)流中执行lm():模型公式中的无效项错误,r,group-by,dplyr,lm,R,Group By,Dplyr,Lm,我打算在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 %>% gr

我打算在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]
)
d=data.frame(
性别=c(“M”、“F”),
年龄=rnorm(20,平均值=40,标准差=3),
重量=rnorm(20,平均值=70,标准差=5)
)
适合百分比组别(性别)%>%
总结(
截距=coef(lm(重量~年龄))[1],
斜率=系数(lm(重量~年龄))[2]
)
错误:模型公式中的术语无效


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

fit <- d %>% group_by(Gender) %>% 
       do(model = lm(Weight ~ Age, data=.)) %>% 
       mutate(Intercept=coef(model)[1], Slope=coef(model)[2]) %>%
       select(-model)
fit%groupby(性别)%>%
do(型号=lm(体重~年龄,数据=)%>%
突变(截距=coef(模型)[1],斜率=coef(模型)[2])%>%
选择(-model)

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

更简单的解决方案甚至是使用
扫帚<代码>扫帚::整洁
将模型输出重新排列为整洁的数据帧,您不必手动访问单个系数。有关更多信息,请参见
渐晕(扫帚)

库(dplyr)
图书馆(扫帚)
适合百分比组(按性别)%>%do(数据框(整洁(lm(体重~年龄,数据=))
适合
来源:本地数据帧[4 x 6]
团体:性别[2]
性别术语估计标准误差统计p值
(fctr)(chr)(dbl)(dbl)(dbl)(dbl)(dbl)
1 F(截距)92.5751034 37.6736331 2.4572916 0.039485169
2 F年龄-0.5132374 0.9098960-0.5640616 0.588172020
3米(截距)41.4985927 10.4958042 3.9538269 0.004213341
4米年龄0.7346306 0.2691001 2.7299529 0.025847680

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

此外,对于复杂的模型,最好只运行一次回归。如何在这样的管道流程中完成它?尝试
do
而不是
summary
。感谢coffeinjunky提供的最佳实践建议。我已经标出了我喜欢的答案,但两种方法都很有效。这里只是一个关于管道的问题。为什么将管道与传统的
function1(function2(function3(x))
样式混合使用?难道不可能一路用管道输送吗?好问题。我的理解是,
do
类似于
summary
mutate
,您也可以使用传统的函数调用。例如,您不会编写
groupby(Gender)%%>%mean(var)%%>%summary
,而不是
groupby(Gender)%%>%summary(mean(var))
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