问:在R dplyr管道中,如何将一些中间输出分配给临时变量以便在管道中进一步使用?
我的方法可行。但它分配到全局框架中,这是不可取的。必须有更好的方法,对吗?我认为我的方法涉及评论线将得到预期的结果。没有骰子。困惑为什么不起作用。
df <- data.frame(a = LETTERS[1:3], b=1:3)
df %>%
filter(b < 3) %>%
assign("tmp", ., envir = .GlobalEnv) %>% # works
#assign("tmp", .) %>% # doesn't work
mutate(b = b*2) %>%
bind_rows(tmp)
a b
1 A 2
2 B 4
3 A 1
4 B 2
答案 0 :(得分:13)
这不在全球环境中创建一个对象:
df %>%
filter(b < 3) %>%
{
{ . -> tmp } %>%
mutate(b = b*2) %>%
bind_rows(tmp)
}
如果您使用. ->> tmp
代替. -> tmp
或将其插入管道,也可以用于调试:
{ browser(); . } %>%
答案 1 :(得分:9)
pipeR
是一个扩展管道功能而不添加不同管道的软件包(如magrittr
所做)。要进行分配,请将括号中带有~
的变量名称作为管道中的元素传递:
library(dplyr)
library(pipeR)
df %>>%
filter(b < 3) %>>%
(~tmp) %>>%
mutate(b = b*2) %>>%
bind_rows(tmp)
## a b
## 1 A 2
## 2 B 4
## 3 A 1
## 4 B 2
tmp
## a b
## 1 A 1
## 2 B 2
虽然语法不是非常具有描述性,但pipeR
为very well documented。
答案 2 :(得分:6)
我经常发现需要在管道中保存中间产品。虽然我的用例通常是为了避免重复过滤器以便以后进行拆分,操作和重组,但这种技术在这里可以很好地工作:
df %>%
filter(b < 3) %>%
{. ->> intermediateResult} %>% # this saves intermediate
mutate(b = b*2) %>%
bind_rows(intermediateResult)
答案 3 :(得分:4)
您可以在管道中需要的位置生成所需的对象。例如:
df %>% filter(b < 3) %>% mutate(b = b*2) %>%
bind_rows(df %>% filter(b < 3))
此方法避免了必须过滤两次:
df %>%
filter(b < 3) %>%
bind_rows(., mutate(., b = b*2))
答案 4 :(得分:0)
我对调试感兴趣(想要保存中间结果,以便我可以从控制台检查和操作它们,而不必将管道分成两个很麻烦的部分。所以,就我的目的而言, OP解决方案原始解决方案的唯一问题是它略显冗长。
这可以通过定义辅助函数来解决:
to_var <- function(., ..., env=.GlobalEnv) {
var_name = quo_name(quos(...)[[1]])
assign(var_name, ., envir=env)
.
}
然后可以按如下方式使用:
df <- data.frame(a = LETTERS[1:3], b=1:3)
df %>%
filter(b < 3) %>%
to_var(tmp) %>%
mutate(b = b*2) %>%
bind_rows(tmp)
# tmp still exists here
仍然使用全局环境,但您也可以显式传递更多本地环境,如下例所示:
f <- function() {
df <- data.frame(a = LETTERS[1:3], b=1:3)
env = environment()
df %>%
filter(b < 3) %>%
to_var(tmp, env=env) %>%
mutate(b = b*2) %>%
bind_rows(tmp)
}
f()
# tmp does not exist here
accepted solution的问题在于,它似乎没有开箱即用的整流管。
G. Grothendieck's solution根本不适用于调试用例。(更新:请参阅下面的G. Grothendieck的评论及其更新后的答案!)
最后,assign("tmp", .) %>%
不起作用的原因是assign()
的默认'envir'参数是“当前环境”(参见documentation for assign),每个阶段都不同管道。要查看此信息,请尝试在各个点将{ print(environment()); . } %>%
插入管道,并查看每次都打印不同的地址。 (可能可以调整to_var的定义,以便默认为祖父母环境。)