【问题标题】:Why does pipe inside if() function fail when first argument is referred with a '.'当第一个参数用“。”引用时,为什么 if() 函数内部的管道会失败
【发布时间】:2021-03-30 01:40:38
【问题描述】:

我花了 45 分钟让一个非常简单的 if() 在循环中工作,但我想了解它为什么会失败。

这是一个简单的 R Magrittr 管道链,大括号 if() 条件{}

这是简化的代表(可重现的示例)

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(),请告诉我,该方法可以概括为从用户输入中获取列名到函数

【问题讨论】:

    标签: r if-statement tidyverse magrittr


    【解决方案1】:

    有两个问题:

    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 }
    

    【讨论】:

    • 糟糕。我用包含的数据a 编辑了我的reprex。出于某种原因,我有一个误解,即大括号{} 中的管道部分定义了一个函数(一元运算符)而不对其进行评估,但你是对的,从'。'开始。导致此行为 - 来源:Magrittr intro 第 6 点
    • 那么说像(.) 这样包围点是否会强制评估函数从而返回值而不是函数?我想我期待它被评估,因为整个内部管道已经用大括号括起来了:if(--internal pipe--)
    • 没有。如果使用 (.) 则不再定义函数。
    猜你喜欢
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-02-13
    • 2018-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多