我经常喜欢对R数据中两个变量相关的多个模型进行拟合和检查。
我可以使用这样的语法来做到这一点:
require(tidyverse)
require(broom)
models <- list(hp ~ exp(cyl), hp ~ cyl)
map_df(models, ~tidy(lm(data=mtcars, formula=.x)))但我已经习惯了管道语法,并希望能够这样做:
mtcars %>% map_df(models, ~tidy(lm(data=., formula=.x)))这表明我从mtcars开始,然后对它做一些事情来生成我的输出。但是这个语法不起作用,给出了一个错误Error: Index 1 must have length 1。
是否有一种方式来编写我的purrr:map()函数,以便将mtcars输送到其中以获得与上面的工作代码相同的输出?也就是说。
mtcars %>% <<<something>>>发布于 2018-02-05 08:53:14
tl/dr:mtcars %>% {map_df(models, function(.x) tidy(lm(data=., formula=.x)))}
或mtcars %>% map_df(models, ~tidy(lm(..1,..2)), ..2 = .)
您尝试过的解决方案有两个问题。
首先,如果你想把圆点放在一个不寻常的地方,你需要使用花括号。
library(magrittr)
1 %>% divide_by(2) # 0.5 -> this works
1 %>% divide_by(2,.) # 2 -> this works as well
1 %>% divide_by(2,mean(.,3)) # this doesn't
1 %>% divide_by(.,2,mean(.,3)) # as it's equivalent to this one
1 %>% {divide_by(2,mean(.,3))} # but this one works as it forces all dots to be explicit.第二个问题是,您不能以您想要的方式使用~公式中的点,尝试map(c(1,2), ~ 3+.)和map(c(1,2), ~ 3+.x) (甚至map(c(1,2), ~ 3+..1)),您就会看到同样的结果。当您在~公式中使用点时,它不再链接到管道函数。
为了确保点被解释为mtcars,您需要使用好的旧function(x) ...定义。
这样做是可行的:
mtcars %>% {map_df(models, function(.x) tidy(lm(data=., formula=.x)))}最后,作为奖励,以下是我想出的,试图找到一个没有花括号的解决方案:
mtcars %>% map(models,lm,.) %>% map_df(tidy)
mtcars %>% map_df(models, ~tidy(lm(..1,..2)), ..2 = .)发布于 2018-02-05 18:21:34
这应该有效,并且不涉及function或{}的复杂性。纯粹的purrr解决方案。
library(tidyverse)
library(broom)
models <- list(hp ~ exp(cyl), hp ~ cyl)
mtcars %>%
list %>% # make it a list
cross2(models) %>% # get combinations
transpose %>% # put into a nice format
set_names("data", "formula") %>% # set names to lm arg names
pmap(lm) %>% # fit models
map_df(tidy) # tidy it up发布于 2018-02-04 21:51:57
这与purrr::map的工作方式有些不一致。您正在模型列表上映射(一次映射列表中的一项),而不是dataframe (一次将是dataframe的一列)。由于dataframe与其他模型表达式保持不变,所以我认为映射在这种情况下是行不通的。
但是,您可以从基于上面的自定义函数中获得所需的语法。
library(tidyverse)
library(broom)
models <- list(hp ~ exp(cyl), hp ~ cyl)
models_to_rows <- function(data, models_list) {
models_list %>%
map_df(~tidy(lm(data=data, formula=.x)))
}
mtcars %>%
models_to_rows(models)
#> term estimate std.error statistic p.value
#> 1 (Intercept) 89.60052274 9.702303069 9.234975 2.823542e-10
#> 2 exp(cyl) 0.04045315 0.004897717 8.259594 3.212750e-09
#> 3 (Intercept) -51.05436157 24.981944312 -2.043650 4.985522e-02
#> 4 cyl 31.95828066 3.883803355 8.228604 3.477861e-09https://stackoverflow.com/questions/48587951
复制相似问题