如何将管道输出传入purrr map构建单管道?解决env参数类型错误
解决管道与purrr map整合时的作用域问题
你遇到的错误是因为purrr公式函数(~)里的.会被优先解析为当前迭代的元素,而不是管道传递过来的整个数据框。当你在glm(reformulate(.x, "a"), data = ., ...)里写data = .时,这个.实际是names(.)[-1]里的单个列名(字符型),自然会报错说“无效的环境参数类型为字符”。
下面给你两种可行的解决方案:
方案1:用临时变量明确指定数据框
在大括号内先把管道传递的数据框赋值给一个临时变量,这样就能彻底避免作用域混淆:
library(tidyverse) my_tbl <- tibble(a = rep(c(0, 1), each = 5), b = rep(c(0, 1), times = 5), c = runif(10), d = rexp(10)) %>% mutate_at(vars(1,2), as.factor) %>% { # 把管道传来的数据框存为临时变量tbl tbl <- . # 迭代列名,用tbl作为glm的数据源 map(names(tbl)[-1], ~glm(reformulate(.x, "a"), data = tbl, family = "binomial")) %>% # 对每个模型单独调用summary,返回结构化的summary对象列表 map(summary) }
方案2:使用匿名函数代替公式语法
用标准的匿名函数(function(x))代替purrr的公式语法,这样函数内的.会保留管道传递的数据框的含义,不会和迭代变量冲突:
library(tidyverse) my_tbl <- tibble(a = rep(c(0, 1), each = 5), b = rep(c(0, 1), times = 5), c = runif(10), d = rexp(10)) %>% mutate_at(vars(1,2), as.factor) %>% { map(names(.)[-1], function(x) { glm(reformulate(x, "a"), data = ., family = "binomial") }) %>% map(summary) }
额外提示
你原来的非管道代码里map(...) %>% summary()其实是对整个模型列表调用summary,这会直接打印所有模型的结果但不会返回结构化的列表。用map(summary)会返回每个模型的summary对象组成的列表,更方便后续提取结果(比如系数、p值等)。
内容的提问来源于stack exchange,提问作者Andrej
相关产品推荐
相关产品推荐

