首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用管道语法处理模型列表

使用管道语法处理模型列表
EN

Stack Overflow用户
提问于 2018-02-02 17:30:24
回答 3查看 682关注 0票数 5

我经常喜欢对R数据中两个变量相关的多个模型进行拟合和检查。

我可以使用这样的语法来做到这一点:

代码语言:javascript
复制
require(tidyverse)
require(broom)
models <- list(hp ~ exp(cyl), hp ~ cyl)
map_df(models, ~tidy(lm(data=mtcars, formula=.x)))

但我已经习惯了管道语法,并希望能够这样做:

代码语言:javascript
复制
mtcars %>% map_df(models, ~tidy(lm(data=., formula=.x)))

这表明我从mtcars开始,然后对它做一些事情来生成我的输出。但是这个语法不起作用,给出了一个错误Error: Index 1 must have length 1

是否有一种方式来编写我的purrr:map()函数,以便将mtcars输送到其中以获得与上面的工作代码相同的输出?也就是说。

代码语言:javascript
复制
mtcars %>% <<<something>>>
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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 = .)

您尝试过的解决方案有两个问题。

首先,如果你想把圆点放在一个不寻常的地方,你需要使用花括号。

代码语言:javascript
复制
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) ...定义。

这样做是可行的:

代码语言:javascript
复制
mtcars %>% {map_df(models, function(.x) tidy(lm(data=., formula=.x)))}

最后,作为奖励,以下是我想出的,试图找到一个没有花括号的解决方案:

代码语言:javascript
复制
mtcars %>% map(models,lm,.) %>% map_df(tidy)
mtcars %>% map_df(models, ~tidy(lm(..1,..2)), ..2 = .)
票数 4
EN

Stack Overflow用户

发布于 2018-02-05 18:21:34

这应该有效,并且不涉及function{}的复杂性。纯粹的purrr解决方案。

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2018-02-04 21:51:57

这与purrr::map的工作方式有些不一致。您正在模型列表上映射(一次映射列表中的一项),而不是dataframe (一次将是dataframe的一列)。由于dataframe与其他模型表达式保持不变,所以我认为映射在这种情况下是行不通的。

但是,您可以从基于上面的自定义函数中获得所需的语法。

代码语言:javascript
复制
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-09
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48587951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档