15

我想用 R 中的赋值运算符结束管道。

我的目标(在伪 R 中):

data %>% analysis functions %>% analyzedData

其中data和analyzedData都是data.frame。

我已经尝试了一些变体,每一个都给出了一个独特的错误信息。我尝试过的一些迭代:

data %>% analysis functions %>% -> analyzedData
data %>% analysis functions %>% .-> analyzedData
data %>% analysis functions %>% <-. analyzedData
data %>% analysis functions %>% <- analyzedData

错误信息:

Error in function_list[[k]](value) : 
  could not find function "analyzedData"
Error: object 'analyzedData' not found
Error: unexpected assignment in: ..

更新:我想出的方法是:

data %>% do analysis %>% {.} -> analyzedData

这样,要对长管道进行故障排除/调试,您可以将这两行放入管道中,以最大限度地减少代码重新运行并隔离问题。

data %>% pipeline functions %>% 
   {.}-> tempWayPoint
   tmpWayPoint %>% 
more pipeline functions %>% {.} -> endPipe 
4

5 回答 5

12

作为第一件事做作业可能是最容易的(就像 scoa 提到的那样),但如果你真的想把它放在最后,你可以使用assign

mtcars %>% 
  group_by(cyl) %>% 
  summarize(m = mean(hp)) %>% 
  assign("bar", .)

它将输出存储到“bar”中

或者,您可以只使用->运算符。您在问题中提到了它,但看起来您使用了类似的东西

mtcars %>% -> yourvariable

代替

mtcars -> yourvariable

你不想%>%在前面->

于 2015-07-19T22:59:49.693 回答
7

看起来您正试图%>%用创建新对象的副作用来装饰管道运算符。有人会假设您可以->为此使用赋值运算符,但它不会在管道中工作。这是因为->它的优先级低于用户定义的运算符,例如%>%,这会扰乱解析:您的管道将被解析为(initial_stages) -> (final_stages)无意义的。

一种解决方案是替换->为用户定义的版本。当我们这样做的时候,我们不妨使用这个lazyeval包,以确保它会在它应该去的地方创建对象:

`%->%` <- function(value, x)
{
    x <- lazyeval::lazy(x)
    assign(deparse(x$expr), value, x$env)
    value
}

使用中的一个例子:

smry <- mtcars %>% 
    group_by(cyl) %->%   # ->, not >
    tmp %>%
    summarise(m=mean(mpg))

tmp
#Source: local data frame [32 x 11]
#Groups: cyl
#
#    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#..  ... ...   ... ...  ...   ...   ... .. ..  ...  ...

smry
#Source: local data frame [3 x 2]
#
#  cyl        m
#1   4 26.66364
#2   6 19.74286
#3   8 15.10000
于 2015-07-20T00:12:56.517 回答
5

您可以将管道链视为一个多行函数,它与其他所有多行函数一样工作。保存输出的常用方法是在第一行分配它:

analyzedData <- data %>% analysis functions

就像你会做的那样:

plot <- ggplot(data,aes(x=x,y=x)) +
  geom_point()
于 2015-07-19T22:05:44.073 回答
4

更新:我想出的方法是:data %>% do analysis %>% {.} -> analyzedData

这样,要对长管道进行故障排除/调试,您可以将这两行放入管道中,以最大限度地减少代码重新运行并隔离问题。

data %>% pipeline functions %>% 
   {.}-> tempWayPoint
   tmpWayPoint %>% 
more pipeline functions %>% {.} -> endPipe 

如果您有更好的方法,请告诉我。

于 2015-07-19T22:03:04.793 回答
2

您想要的也可以使用大括号,例如

data %>% analysis_functions %>% {analyzedData <<-.}

您还可以在对象分配后扩展管道。我发现在长链的末尾分配一个数据框非常方便,然后再将其导入 ggplot 或在tidy()ing 之前将模型对象保存用于其他目的。

于 2020-01-31T00:00:17.380 回答