【问题标题】:How do you call a function that takes no inputs within a pipeline?你如何调用一个在管道中不接受输入的函数?
【发布时间】:2022-01-10 00:54:40
【问题描述】:

我尝试搜索此内容,但找不到任何类似的问题。假设,为了一个简单的例子,我想使用dplyr的管道%>%做以下事情。

c(1,3,5) %>% ls() %>% mean()

暂且不说像这样的管道的用例是什么,我如何将不需要来自左侧的任何输入的函数称为“中间管道”,并且只是将它们传递给管道中的下一个函数?基本上,我想在我的管道中加入某种“中断”或“中断”,让该功能完成它的工作,然后继续我的快乐方式。 显然,上面的方法实际上不起作用,我知道 T 管道 %T>% 也不会在这里使用,因为它仍然希望中间函数需要来自 lhs 的输入。这里有没有分配中间对象和重新启动管道的选项?

【问题讨论】:

    标签: r pipe tidyverse pipeline magrittr


    【解决方案1】:

    使用“magrittr”管道运算符,您可以在 {…} 中放置一个操作数,以防止自动参数替换:

    c(1,3,5) %>% {ls()} %>% mean()
    # NA
    # Warning message:
    # In mean.default(.) : argument is not numeric or logical: returning NA
    

    ……但这当然没有用处。

    顺便说一句,管道内的ls() 是在它自己的环境中执行的,而不是在调用环境中执行,所以它在这里的使用甚至不太有用。但是可以使用返回合理值的不同函数,例如:

    c(1,3,5) %>% {rnorm(10)} %>% mean()
    # [1] -0.01068046
    

    或者,如果您打算传递左侧,跳过中间 ls(),您可以执行以下操作:

    c(1,3,5) %>% {ls(); .} %>% mean()
    # [1] 3
    

    ……再说一次,在这里使用ls() 没有意义,但其他一些有副作用的函数会起作用。

    【讨论】:

    • 我想到的函数是gc(),tbh,尽管我知道它可能没有多大作用。我在管道中处理非常大的矩阵,因此在步骤之间清理一些垃圾似乎至少值得一试。
    • @Bajcz 我明白了。是的,如果 gc() 函数确实做了任何事情,那么这个 可能 是一个有效的用例——但正如您所知道的,gc() 实际上并没有做任何有用的事情:如果 R 用完内存分配期间它会自动运行 GC。
    • 好吧,再加上我自己的好奇心! :) 管道很有用...很高兴知道有时您会违反规则...
    【解决方案2】:

    我不知道是否有内置函数,但您当然可以为此创建一个辅助函数

    > callfun <- function(x, fun){fun(); return(x)}
    > c(1, 3, 5) %>% callfun(fun = ls) %>% mean()
    # [1] 3
    

    我真的不明白这一点,但嘿 - 这是你的生活。

    【讨论】:

    • 请参阅上面我对@Konrad Rudolph 的评论。
    【解决方案3】:

    你可以像这样定义一个辅助函数,它接受一个它不使用的参数,以便让它适合管道:

    ls_return_x <- function(x){
      print(ls()) 
      x
    }
    c(1,3,5) %>% ls() %>% mean()
    

    注意,本例中的ls() 调用将在ls_return_x() 函数内打印环境中的对象。如果您想从全局环境中打印环境,请查看 ls() 的帮助页面。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-03
      • 2020-09-15
      • 2022-01-20
      相关资源
      最近更新 更多