how to feed the result of a pipe chain (magrittr) to an object

只愿长相守 提交于 2019-12-03 04:56:14

问题


This is a fairly simply question. But I couldn't find the answer per google/stackexchange and looking at the documentation of magrittr. How do you feed the result of a chain of functions which are connected via %>% to create a vector?

what I saw most people do is:

a <-
data.frame( x = c(1:3), y = (4:6)) %>%
sum()

but is there also a solution where I can just pipe-chain the result to feed it to an object, maybe an alias or sth of the like, somewhat like this:

data.frame( x = c(1:3), y = (4:6)) %>%
sum() %>%
a <- ()

this would help with keeping all of the code in the same logic of feeding results forward "down the pipe".


回答1:


Try this:

data.frame( x = c(1:3), y = (4:6)) %>% sum -> a



回答2:


You can do it like so:

data.frame( x = c(1:3), y = (4:6)) %>%  
sum %>%  
assign(x="a",value=.,pos=1)  

A couple of things to note:

You can use "." to tell magrittr which argument the object being brought forward belongs in. By default it is the first, but here I use the . to indicate that I want it in the second value argument instead.

Second I had to use the pos=1 argument to make the assignment in the global environment.




回答3:


You can also use the <<- operator:

data.frame( x = c(1:3), y = (4:6)) %>%
  sum() %>%
  `<<-`(a,.)

Edit: I think John Paul's is the safest suggestion, and you could keep going with the chain doing different assignments of partial results. For example:

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)

This will correctly create a, b and c.




回答4:


Using pipeR's %>>% this should be very easy.

library(pipeR)
data.frame( x = c(1:3), y = (4:6)) %>>%
  sum %>>%
  (~ a)

The pipeR tutorial may be helpful: http://renkun.me/pipeR-tutorial/ For assignment: http://renkun.me/pipeR-tutorial/Pipe-operator/Pipe-with-assignment.html




回答5:


What I like to do (and I found this trick somewhere I can't remember) is to use {.} -> obj at the end of my pipe-chain. This way I can add extra steps to the end of the chain by just inserting a new line, and not have to re-position to -> assignment operator.

You can also use (.) isntead of {.} but it looks a bit, odd.

For example, instead of this:

  iris %>% 
    ddply(.(Species), summarise, 
          mean.petal = mean(Petal.Length),
          mean.sepal = mean(Sepal.Length)) -> summary

Do this:

iris %>% 
    ddply(.(Species), summarise, 
          mean.petal = mean(Petal.Length),
          mean.sepal = mean(Sepal.Length)) %>% 
    {.} -> summary

It makes it easier to see where your piped data ends up. Also, while it doesn't seem like a big deal, it's easier to add another final step as you don't need to move the -> down to a new line, just add a new line before the {.} and add the step.

Like so:

iris %>% 
    ddply(.(Species), summarise, 
          mean.petal = mean(Petal.Length),
          mean.sepal = mean(Sepal.Length)) %>% 
    arrange(desc(mean.petal)) %>%   # just add a step here
    {.} -> summary

This doesn't help with saving intermediate results though. John Paul's answer to use assign() is nice, but its a bit long to type. You need to use the . since the data isn't the first argument, you have to put the name of the new argument in ""'s, and specify the environment (pos = 1). It seems lazy on my part, but using %>% is about speed.

So I wrapped the assign() in a little function which speeds it up a bit:

keep <- function(x, name) {assign(as.character(substitute(name)), x, pos = 1)}

So now you can do this:

  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


来源:https://stackoverflow.com/questions/25975827/how-to-feed-the-result-of-a-pipe-chain-magrittr-to-an-object

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!