我喜欢做的事情(我记不起来了,在某个地方发现了这个技巧)是在我的管道链末尾使用
{.} -> obj
。这样,我可以通过插入新行向链的末尾添加额外步骤,而不必重新定位到
->
赋值运算符。
您还可以使用
(.)
代替
{.}
,但它看起来有点奇怪。
例如,可以这样做:
iris %>%
ddply(.(Species), summarise,
mean.petal = mean(Petal.Length),
mean.sepal = mean(Sepal.Length)) -> summary
请执行以下操作:
iris %>%
ddply(.(Species), summarise,
mean.petal = mean(Petal.Length),
mean.sepal = mean(Sepal.Length)) %>%
{.} -> summary
这样做可以更容易地看到你的管道数据最终输出的位置。此外,虽然这似乎不是什么大问题,但是添加另一个最终步骤会更加容易,因为你不需要将->
移动到新行,只需在{.}
之前添加一个新行并添加该步骤即可。
就像这样:
iris %>%
ddply(.(Species), summarise,
mean.petal = mean(Petal.Length),
mean.sepal = mean(Sepal.Length)) %>%
arrange(desc(mean.petal)) %>% # just add a step here
{.} -> summary
这并不能帮助节省中间结果。John Paul的使用assign()方法的答案很好,但是它有点长,需要使用".",因为数据不是第一个参数,所以必须将新参数的名称放在""中,并指定环境(pos = 1)。这似乎是我懒惰的表现,但使用%>%是关于速度的。因此,我将assign()方法包装在一个小函数中,以加快速度:
keep <- function(x, name) {assign(as.character(substitute(name)), x, pos = 1)}
现在你可以这样做:
keep <- function(x, name) {assign(as.character(substitute(name)), x, pos = 1)}
iris %>%
ddply(.(Species), summarise,
mean.petal = mean(Petal.Length),
mean.sepal = mean(Sepal.Length)) %>% keep(unsorted.data) %>%
arrange(mean.petal) %>%
{.} -> sorted.data
sorted.data
unsorted.data
->
的正当理由,现在有了! - Carlos Cinelli->
,你就不能继续链式操作:例如data.frame(x = c(1:3), y = (4:6)) %>% sum -> a %>% exp
会出错,你必须使用圆括号(data.frame(x = c(1:3), y = (4:6)) %>% sum -> a) %>% (exp)
,如果不小心可能会导致意外的结果。 - Carlos Cinellidata.frame(x = c(1:3), y = (4:6)) %>% sum -> a; a %>% exp
来避免问题。(2) 在一半的过程中赋值是副作用,而函数式编程的风格是避免副作用。 - G. Grothendiecktee=function(v,n){assign(n,v,.GlobalEnv);v}
然后使用管道符d %>% whatever %>% tee("part1") %>% otherstuff %>% tee("part2") %>% etcetc
。 - Spacedman