【问题标题】:How to select_if in dplyr, where the logical condition is negated如何在dplyr中选择_if,其中逻辑条件被否定
【发布时间】:2018-12-23 19:09:47
【问题描述】:

我想从数据框中选择所有数字列,然后选择所有非数字列。一个明显的方法是:-

mtcars %>%
    select_if(is.numeric) %>%
    head()

这完全符合我的预期。

mtcars %>%
    select_if(!is.numeric) %>%
    head()

这不会,并产生错误消息!is.numeric 中的错误:无效参数类型

寻找另一种方法来做同样的事情:-

mtcars %>%
    select_if(sapply(., is.numeric)) %>%
    head()

完美运行,但是

mtcars %>%
    select_if(sapply(., !is.numeric)) %>%
    head()

失败并显示相同的错误消息。 (purrr::keep 的行为方式完全相同)。

在这两种情况下,使用 - 删除不需要的列也失败了,与上面 is.numeric 版本的错误相同,而 sapply 版本的此错误消息 Error: Can '不将整数向量转换为函数.

is.numeric 的帮助页面显示

is.numeric 是一个内部通用原始函数:您可以编写方法来处理特定类的对象,请参阅 InternalMethods。 ... is.numeric 的方法只有在类的基类型是双精度或整数并且值可以合理地被视为数字时才返回 true(例如,对它们进行算术运算是有意义的,并且应该通过基类型进行比较) .

帮助页面!说

价值

对于 !,与 x 长度相同的逻辑或原始向量(对于原始 x):名称、dims 和 dimnames 从 x 以及所有其他属性(包括类)复制(如果未进行强制)。

查看有用的问题Negation ! in a dplyr pipeline %>% 我可以看到这不起作用的一些原因,但那里建议的解决方案都不起作用。

mtcars %>%
    select_if(not(is.numeric())) %>%
    head()

给出合理的错误 is.numeric() 中的错误:0 个参数传递给 'is.numeric' 这需要 1 个

mtcars %>%
    select_if(not(is.numeric(.))) %>%
    head()

失败并出现此错误:- tbl_if_vars(.tbl, .predicate, caller_env(), .include_group_vars = TRUE) 中的错误:length(.p) == length(tibble_vars) 不正确

这种行为肯定违反了最小意外原则。现在这对我来说影响不大,但它表明我未能理解一些更基本的观点。

有什么想法吗?

【问题讨论】:

    标签: r function select dplyr


    【解决方案1】:

    否定一个谓词函数可以用专用的Negate()purrr::negate()函数来完成(而不是!运算符,它否定一个向量):

    library(dplyr)
    
    mtcars %>% 
      mutate(foo = "bar") %>% 
      select_if(Negate(is.numeric)) %>% 
      head()
    
    #   foo
    # 1 bar
    # 2 bar
    # 3 bar
    # 4 bar
    # 5 bar
    # 6 bar
    

    或者(purrr::negate()(小写)的行为略有不同,请参阅相应的帮助页面):

    library(purrr)
    library(dplyr)
    
    mtcars %>% 
      mutate(foo = "bar") %>% 
      select_if(negate(is.numeric)) %>% 
      head()
    
    #   foo
    # 1 bar
    # 2 bar
    # 3 bar
    # 4 bar
    # 5 bar
    # 6 bar
    

    【讨论】:

      【解决方案2】:
      mtcars %>%
        select_if(funs(!is.numeric(.))) %>%
        head()
      

      做同样的事情

      【讨论】:

        【解决方案3】:

        您可以定义自己的“不是数字”函数,然后使用它来代替

        is_not_num <- function(x) !is.numeric(x)
        
        mtcars %>%
        select_if(is_not_num) %>%
        head()
        

        【讨论】:

          猜你喜欢
          • 2015-01-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多