r-如何将管道链(magrittr)的结果馈送到对象



这是一个相当简单的问题。但我在谷歌/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)

这将正确创建abc

使用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

相关内容

  • 没有找到相关文章

最新更新