微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我花了 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 年 3 月 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 }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。