如何在dplyr中选择select_if,其中逻辑条件否定 [英] How to select_if in dplyr, where the logical condition is negated

查看:262
本文介绍了如何在dplyr中选择select_if,其中逻辑条件否定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从数据框中选择所有数字列,然后选择所有非数字列.一种明显的方法如下:-

I want to select all numeric columns from a dataframe, and then to select all the non-numeric columns. An obvious way to do this is the following :-

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

这完全符合我的预期.

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

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

This doesn't, and produces the error message Error in !is.numeric : invalid argument type

寻找另一种做同一件事的方法:-

Looking at another way to do the same thing :-

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

工作正常,但是

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

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

fails with the same error message. (purrr::keep behaves exactly the same way).

在两种情况下,使用-删除不希望的列也都失败,对于is.numeric版本,该错误消息与上面相同,并且对于sapply版本的此错误消息错误:可以:不会将整数向量转换为函数.

In both cases using - to drop the undesired columns fails too, with the same error as above for the is.numeric version, and this error message for the sapply version Error: Can't convert an integer vector to function.

is.numeric的帮助页面说

The help page for is.numeric says

is.numeric是一个内部通用基元函数:您可以编写处理特定对象类的方法,请参见InternalMethods. ... is.numeric的方法仅应在该类的基本类型为double或integer且可以合理地将值视为数字的情况下返回true(例如,对它们进行算术运算是有意义的,并且应该通过基本类型进行比较)

is.numeric is an internal generic primitive function: you can write methods to handle specific classes of objects, see InternalMethods. ... Methods for is.numeric should only return true if the base type of the class is double or integer and values can reasonably be regarded as numeric (e.g., arithmetic on them makes sense, and comparison should be done via the base type).

的帮助页面!说

对于!,具有与x相同长度的逻辑或原始向量(对于原始x):从x复制名称,暗号和暗名,如果不进行强制转换,则复制所有其他属性(包括类).

For !, a logical or raw vector(for raw x) of the same length as x: names, dims and dimnames are copied from x, and all other attributes (including class) if no coercion is done.

查看有用的问题 dplyr管道%>% ! >我可以看到一些不起作用的原因,但是那里提出的解决方案都不起作用.

Looking at the useful question Negation ! in a dplyr pipeline %>% I can see some of the reasons why this doesn't work, but neither of the solutions suggested there works.

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)不正确.

Fails with this error :- Error in tbl_if_vars(.tbl, .predicate, caller_env(), .include_group_vars = TRUE) : length(.p) == length(tibble_vars) is not TRUE.

这种行为肯定违反了最少惊奇的原则.现在这对我来说并不重要,但这表明我无法理解一些更基本的观点.

This behaviour definitely violates the principle of least surprise. It's not of great consequence to me now, but it suggests I am failing to understand some more fundamental point.

有什么想法吗?

推荐答案

使用专有的Negate()purrr::negate()函数(而不是!运算符)可以使谓词函数取反. ,它会否定 vector ):

Negating a predicate function can be done with the dedicated Negate() or purrr::negate() functions (rather than the ! operator, that negates a vector):

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()(小写)的行为略有不同,请参见相应的帮助页面):

Or (purrr::negate() (lower-case) has slightly different behavior, see the respective help pages):

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

这篇关于如何在dplyr中选择select_if,其中逻辑条件否定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆