【问题标题】:Reason for magrittr pipe (%>%) with ifelse behavior?带有ifelse行为的magrittr管道(%>%)的原因?
【发布时间】:2018-04-17 00:28:18
【问题描述】:

我在条件分支和 ifelse 分支中都使用转发结果的场景中将 ifelse 与管道一起使用。下面是一个简化版本:ifelse + pipe 似乎只处理与. 不同的条件,如果放在花括号内。

library("magrittr")

FALSE %>%  ifelse(., 'true', 'false')
#> [1] "false"

FALSE %>%  ifelse(. == TRUE, 'true', 'false')
#> Error in ifelse(., . == TRUE, "true", "false"): unused argument ("false")

FALSE %>%  {ifelse(. == TRUE, 'true', 'false')}
#> [1] "false"

我最初的目标:

library("magrittr")

NULL %>% ifelse(is.null(.), "", as.character(.))
#> Error in ifelse(., is.null(.), "", as.character(.)): unused argument (as.character(.))

NULL %>% {ifelse(is.null(.), "", as.character(.))}
#> [1] ""

使用{} 对我来说已经足够了,但我想了解这种行为的原因。

编辑: 尽管this 问题讨论了一个相关主题,并且我最初看到将 ifelse 放在花括号内的想法,但在表达式/函数调用中仅使用 . 或使用 . 之间没有区别,这是我的重点问题。

【问题讨论】:

标签: r magrittr


【解决方案1】:

magrittr 文档说,当在嵌套函数调用中使用点时,它的行为与您看到的一样。

将圆点用于次要目的
通常,除了 lhs 本身的值之外,在 rhs 调用中还需要 lhs 的某些属性或属性,例如行数或列数。在 rhs 调用中多次使用点占位符是完全有效的,但根据设计,在嵌套函数调用中使用它时行为会略有不同。 特别是,如果占位符仅用于嵌套函数调用,lhs 也会作为第一个参数放置! 这样做的原因是在大多数用例中这会产生最易读的代码。

例如,iris %>% subset(1:nrow(.) %% 2 == 0) 等价于 iris %>% subset(., 1:nrow(.) %% 2 == 0),但更紧凑。可以通过将 rhs 括在大括号中来推翻此行为。例如,1:10 %>% {c(min(.), max(.))} is equivalent to c(min(1:10), max(1:10))

所以推荐的解决方案实际上是使用你已经找到的花括号。

逻辑评估似乎是 ifelse 内的单独函数调用,因此它的行为如此。

【讨论】:

    【解决方案2】:

    我认为错误信息很清楚。

    • 当您使用{} 时,{} 中的. 将替换为%>% 的左侧。

    • 当你调用一个没有{}的函数时,第一个参数是lhs,而你显式编码的其他参数将向右移动,此外(see here):

    在第一个以外的位置需要 LHS,可以使用 点,'.',作为占位符。

    因此,FALSE %>% ifelse(. == TRUE, 'true', 'false') 实际上是在调用:

    ifelse(FALSE, FALSE == TRUE, 'true', 'false')
    

    FALSE %>% {ifelse(. == TRUE, 'true', 'false')}实际上正在调用:

    ifelse(FALSE == TRUE, 'true', 'false')
    

    【讨论】:

      【解决方案3】:

      也许这对您的情况会更令人满意:

      NULL %>% as.character %>% inset(length(.)==0, value ="")
      

      【讨论】:

      • 我发现了一个类似的,使用 %||% from purrr 的方法更短:NULL %>% {as.character(. %||% "")}
      猜你喜欢
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-02
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 2018-07-23
      • 1970-01-01
      相关资源
      最近更新 更多