我希望做的是将mtcars数据集中的mpg(每英里加仑数)转换为gpm(每英里消耗的加仑数),并将其与wt拟合成一个模型。看起来很简单:
data(mtcars)
library(dplyr)
library(tidyr)
library(broom)
library(ggplot2)
library(scales)
mtcars2 <-
mtcars %>%
mutate(gpm = 1 / mpg) %>%
group_by(cyl, am)
lm1 <-
mtcars2 %>%
do(fit = lm(gpm ~ wt, data = .))
这使我得到了一个行数据框,有6行,正如预期的那样。
这张图证实了有六个组:
p1 <-
qplot(wt, gpm, data = mtcars2) +
facet_grid(cyl ~ am) +
stat_smooth(method='lm',se=FALSE, fullrange = TRUE) +
scale_x_continuous(limits = c(0,NA))
我可以使用augment()函数来获取拟合后的输出:
lm1 %>% augment(fit)
这给我32行,每一行对应mtcars2中的一行,正如预期的那样。
现在的挑战是:我想使用新数据得到拟合输出,其中我已经将wt增加了cyl/4:
newdata <-
mtcars2 %>%
mutate(
wt = wt + cyl/4)
我希望这将产生一个数据框,其大小与lm1%>%augment(fit)相同:每个newdata中的行都对应一行,因为broom将通过grouping变量cyl和am匹配模型和newdata。
不幸的是,
pred1 <-
lm1 %>%
augment(
fit,
newdata = newdata)
这将为我提供一个数据框,其中包含192行(= 6 x 32),显然将每个模型适合于newdata的每一行。
从其他地方阅读,我了解到group_by和rowwise数据框不兼容,因此lm1未分组,augment无法关联模型和newdata。是否有另一种设计模式可以让我做到这一点?如果它像上面的尝试那样简单透明,那就太好了,但更重要的是它能工作。
这是我的sessionInfo():
> sessionInfo()
R version 3.3.1 (2016-06-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] scales_0.4.0 ggplot2_2.1.0 broom_0.4.1 tidyr_0.6.0 dplyr_0.5.0
loaded via a namespace (and not attached):
[1] Rcpp_0.12.7 magrittr_1.5 mnormt_1.5-4 munsell_0.4.3
[5] colorspace_1.2-6 lattice_0.20-34 R6_2.1.3 stringr_1.1.0
[9] plyr_1.8.4 tools_3.3.1 parallel_3.3.1 grid_3.3.1
[13] nlme_3.1-128 gtable_0.2.0 psych_1.6.9 DBI_0.5-1
[17] lazyeval_0.2.0 assertthat_0.1 tibble_1.2 reshape2_1.4.1
[21] labeling_0.3 stringi_1.1.1 compiler_3.3.1 foreign_0.8-67
编辑:
@aosmith:我一直在探索你的第二个选项,我很喜欢它。但当我尝试在我的真实数据上运行它时,在 mutate 命令中出现了一个问题:它返回“错误:augment 不知道如何处理类别为 list 的数据”。
我的实际代码更像是:
newdata %>%
dplyr::select(cyl, am, wt) %>% # wt holds new predictor values
group_by(cyl, am) %>%
nest() %>%
inner_join(regressions, .) %>%
## looks like yours at this point
mutate(pred = list(augment(fit, newdata = data))) %>% # Error here
unnest(pred)
当我说它看起来像是你的时候,我的意思是我有以下列(此处重命名以保持一致):ID(chr)、attr1(dbl)、cyl(dbl)、am(chr)、fit(list)和data(list)。你有cyl、am(dbl)、fit和data。我将我的am更改为dbl,但这并没有帮助。
我认为差别在于,在此样本中,我有3(ID…类似于mtcars中的rownames)×2(cyl)×2(am)个单位(每个样本有12个测量值),而mtcars示例有3(cyl)×2(am)个单元格×每个单元格中的随机数量的汽车类型。在我的分析中,我需要查看ID值,但newdata同样适用于所有单位。如果有所帮助,请将其视为施加在测试中每辆汽车上的顺风速度。这是否说明augment不能处理class list数据的原因?
编辑:将ID与newdata(使用full = TRUE)合并解决了最后一个问题。目前我正在使用您提出的第一个解决方案。