我在使用条件和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放在花括号中的想法,在表达式/函数调用中使用简单.
或使用.
之间没有区别。是我的问题的主要观点。
答案 0 :(得分:7)
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
内的单独函数调用,因此也是它的行为原因。
答案 1 :(得分:2)
我认为错误信息非常清楚。
当您使用{}
时,.
中的{}
将替换为%>%
的左侧。
当您调用不带{}
的函数时,第一个参数是lhs,而您明确编码的其他参数将向右移动,此外(see here):
LHS需要在第一个以外的位置,可以使用 dot,'。',作为占位符。
因此,FALSE %>% ifelse(. == TRUE, 'true', 'false')
实际上是在调用:
ifelse(FALSE, FALSE == TRUE, 'true', 'false')
和FALSE %>% {ifelse(. == TRUE, 'true', 'false')}
实际上是在呼叫:
ifelse(FALSE == TRUE, 'true', 'false')
答案 2 :(得分:1)
也许这会让你的情况更令人满意:
NULL %>% as.character %>% inset(length(.)==0, value ="")