这是一个相当简单的问题。但我在谷歌/stackexchange和magrittr的文档中都找不到答案。如何馈送通过%>%连接的函数链的结果以创建向量?
我看到大多数人做的是:
a <-
data.frame( x = c(1:3), y = (4:6)) %>%
sum()
但是,有没有一个解决方案,我可以直接将结果管道链接到一个对象,可能是一个别名或类似的东西,有点像这样:
data.frame( x = c(1:3), y = (4:6)) %>%
sum() %>%
a <- ()
这将有助于将所有代码保持在相同的逻辑中,将结果"向下传递"。
试试这个:
data.frame( x = c(1:3), y = (4:6)) %>% sum -> a
你可以这样做:
data.frame( x = c(1:3), y = (4:6)) %>%
sum %>%
assign(x="a",value=.,pos=1)
需要注意的几件事:
您可以使用"."来告诉magrittr
要转发的对象属于哪个参数。默认情况下,它是第一个参数,但这里我使用.
来表示我希望它位于第二个value
参数中。
其次,我必须使用pos=1
参数在全局环境中进行赋值。
您也可以使用<<-
运算符:
data.frame( x = c(1:3), y = (4:6)) %>%
sum() %>%
`<<-`(a,.)
编辑:我认为John Paul的建议是最安全的,你可以继续使用链来分配不同的部分结果。例如:
data.frame( x = c(1:3), y = (4:6)) %>%
sum %>%
assign(x="a",value=., pos=1) %>%
exp %>%
assign(x="b",value=., pos=1) %>%
sqrt %>%
assign(x="c", value=., pos=1)
这将正确创建a
、b
和c
。
使用pipeR的%>>%
应该非常容易。
library(pipeR)
data.frame( x = c(1:3), y = (4:6)) %>>%
sum %>>%
(~ a)
piperR教程可能会有所帮助:http://renkun.me/pipeR-tutorial/对于分配:http://renkun.me/pipeR-tutorial/Pipe-operator/Pipe-with-assignment.html
我喜欢做的(我在不记得的地方发现了这个技巧)是在管道链的末端使用{.} -> 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) %>% # keep this step
arrange(mean.petal) %>%
{.} -> sorted.data
sorted.data
# Species mean.petal mean.sepal
#1 setosa 1.462 5.006
#2 versicolor 4.260 5.936
#3 virginica 5.552 6.588
unsorted.data
# Species mean.petal mean.sepal
#1 setosa 1.462 5.006
#2 versicolor 4.260 5.936
#3 virginica 5.552 6.588