【问题标题】:How do you end a pipe with an assignment operator?如何用赋值运算符结束管道?
【发布时间】:2015-10-08 23:30:02
【问题描述】:

我想用 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 

【问题讨论】:

  • analyzedData &lt;- data %&gt;% analysis functions
  • 你的标题有点误导;您真正想要做的是将分配交错到管道中,而不是结束它。
  • @Hong-Ooi 我来到这里是因为我的问题是标题中的问题,事实上,事实证明这不是问题。但是对于像我这样想要回答这个问题的人来说,答案是中缀函数[&lt;- ()。 (我无法正确使用反引号;[&lt;- 在反引号中)。第一个参数是要子集然后分配的对象(以便通过管道输入),下一个参数是该对象的维度的子集(每个一个),最后一个是要分配给该子集的对象,或者覆盖它。

标签: r dplyr magrittr


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 你不需要%&gt;% {.}。你可以做pipeline_functions -&gt; tmpWaypoint
    【解决方案3】:

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

    解决方案是将-&gt; 替换为用户定义的版本。当我们这样做的时候,我们不妨使用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
    

    【讨论】:

      【解决方案4】:

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

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

      它将输出存储到“bar”中

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

      mtcars %>% -> yourvariable
      

      而不是

      mtcars -> yourvariable
      

      你不想在-&gt;前面有%&gt;%

      【讨论】:

      • 谢谢,这似乎可以解决问题。您知道使用 '{.} -> endPipe' 与 'assign("endPipe", .)' 的相对优点吗?我看到 assign 允许您将环境指定为参数。除此之外,如果我们只对分配到当前环境感兴趣,那么一个比另一个更好吗?只是风格上的差异吗?
      • 我试过这个,但分配不起作用。代码评估,但我没有得到一个名为“bar”的新对象。
      • @ccoffman 你应该得到一个名为“bar”的新对象。它将在当前环境中进行评估,因此如果您在函数内部执行此操作,然后在函数退出后寻找“bar”,那么“bar”将不再存在。不过,这更像是一个范围界定问题。
      • 我遇到了和科夫曼一样的问题。正如@Dason 建议的那样,代码没有在函数中运行。将分配语句更改为 assign("bar", .,envir = .GlobalEnv) 确实解决了问题。我正在使用 R 版本 3.4.1。
      • 以这种方式对管道使用 assign() 在 R 3.5.2 和 marittr 1.5 中不起作用。使用 pos= 参数显式设置环境以将变量分配到(例如 pos=1)。或者,按照 @Wilbert 并使用 envir= 参数。
      【解决方案5】:

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

      analyzedData <- data %>% analysis functions
      

      就像你会做的那样:

      plot <- ggplot(data,aes(x=x,y=x)) +
        geom_point()
      

      【讨论】:

        猜你喜欢
        • 2021-05-03
        • 2011-08-02
        • 2019-10-06
        • 2011-11-16
        • 1970-01-01
        • 1970-01-01
        • 2013-11-30
        • 2015-10-02
        • 1970-01-01
        相关资源
        最近更新 更多