当第一个参数用“.”引用时,为什么 if() 函数内部的管道会失败

Why does pipe inside if() function fail when first argument is referred with a '.'

我花了 45 分钟让一个非常简单的 if() 在循环中工作,但我想首先了解它失败的原因。

这是一个简单的 R Magrittr 管链,在大括号 {}

中带有 if() 条件

这是简化的 reprex(可重现的例子)

library(tidyverse) # load tidyverse library

a <- tibble(a1 = 1:6, a2 = 6:1, a3 = rep(c('a', 'b'),3), a4 = as_factor(5:10))

# function to check the data type of a column

# Fails
check1 <- function(.df, .colm)
{
  .df %>%
     { if(. %>% pull(var = {{.colm}}) %>% is.character()) 1 else 2} # pull .colm from .df and check if is char

}

# Works
check2 <- function(.df, .colm)
{
  .df %>%
    {if(pull(., var = {{.colm}}) %>% is.character()) 1 else 2} # pull .colm from .df and check if is char
  
}

check1(a, a1) # Fails
#> Error in if (. %>% pull(var = {: argument is not interpretable as logical
check2(a, a1) # Works
#> [1] 2

reprex package (v0.3.0)

于 2021-03-30 创建

另外请告诉我是否有更简单的方法来检查数据框中列的 class(),该方法可以概括为将列名从用户输入中提取到函数中

有两个问题:

  1. 调用 check1 和 check2 都出错,因为它们的输入尚未定义

  2. magrittr 管道仅以左侧的一个点开头,它定义了一个函数,因此在第一种情况下,if 的条件部分中的部分定义了一个函数,不符合逻辑条件。

     library(magrittr)
    
     f <- . %>% { . ^ 2 }
     f(3)
     ## [1] 9
    

同样的原因失败了

      library(purrr)
      library(dplyr)

      BOD %>% { if (. %>% pull("demand") %>% is.numeric) 1 else 0 }

但这行得通,因为现在左侧是 (.) 而不是 .

      BOD %>% { if ( (.) %>% pull("demand") %>% is.numeric) 1 else 0 }