ast*_*nes 7 select r function dplyr
我想从数据框中选择所有数字列,然后选择所有非数字列.一个显而易见的方法是: -
mtcars %>%
select_if(is.numeric) %>%
head()
Run Code Online (Sandbox Code Playgroud)
这完全符合我的预期.
mtcars %>%
select_if(!is.numeric) %>%
head()
Run Code Online (Sandbox Code Playgroud)
这不会,并产生错误消息错误!is.numeric:无效的参数类型
看另一种做同样事情的方法: -
mtcars %>%
select_if(sapply(., is.numeric)) %>%
head()
Run Code Online (Sandbox Code Playgroud)
效果很好,但是
mtcars %>%
select_if(sapply(., !is.numeric)) %>%
head()
Run Code Online (Sandbox Code Playgroud)
失败并显示相同的错误消息.(purrr :: keep表现完全相同).
在这两种情况下使用-删除不需要的列也会失败,与上面的is.numeric版本的错误相同,并且此错误消息为sapply版本错误:无法将整数向量转换为函数.
is.numeric的帮助页面说
is.numeric是一个内部泛型原语函数:您可以编写处理特定类对象的方法,请参阅InternalMethods....如果类的基类型是double或integer,并且值可以合理地视为数值,则is.numeric的方法应该只返回true(例如,对它们的算术是有意义的,并且应该通过基类型进行比较) .
帮助页面!说
值
对于!,与x相同长度的逻辑或原始向量(对于原始x):名称,dims和dimnames是从x复制的,如果没有强制,则复制所有其他属性(包括类).
在dplyr管道中查看有用的问题Negation !,%>%我可以看到为什么这不起作用的一些原因,但是没有一个解决方案表明它有效.
mtcars %>%
select_if(not(is.numeric())) %>%
head()
Run Code Online (Sandbox Code Playgroud)
给出合理的错误 is.numeric()中的错误:传递给'is.numeric'的0个参数需要1.
mtcars %>%
select_if(not(is.numeric(.))) %>%
head()
Run Code Online (Sandbox Code Playgroud)
失败并出现此错误: - tbl_if_vars中的错误(.tbl,.predicate,caller_env(),. include_group_vars = TRUE):length(.p)== length(tibble_vars)不为TRUE.
这种行为绝对违反了最不惊讶的原则.这对我来说并不重要,但它表明我没有理解一些更基本的观点.
有什么想法吗?
Aur*_*èle 11
否定谓词函数可以使用专用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
Run Code Online (Sandbox Code Playgroud)
或(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
Run Code Online (Sandbox Code Playgroud)
您可以定义自己的"非数字"功能,然后使用它
is_not_num <- function(x) !is.numeric(x)
mtcars %>%
select_if(is_not_num) %>%
head()
Run Code Online (Sandbox Code Playgroud)