R dpylr select_if有多个条件

Dav*_*vid 9 select r dplyr

我想按名称选择所有数字变量以及一些变量.我已设法使用select_if来获取数值变量并选择按名称获取,但不能将两者合并为一个语句

x = data.table(c(1,2,3),c(10,11,12),c('a','b','c'),c('x','y','z'), c('l', 'm','n'))
Run Code Online (Sandbox Code Playgroud)

我希望我的结果是:

V1 V2 V4 V5
1 10  x l
2 11  y m
3 12  z n
Run Code Online (Sandbox Code Playgroud)

我试过这个,但它不起作用

y = x %>%
select_if(is.numeric, V4, V5)
Run Code Online (Sandbox Code Playgroud)

aic*_*hao 13

如果我们有数据框,x:

x = data.frame(V1=c(1,2,3),V2=c(10,11,12),V3=c('a','b','c'),V4=c('x','y','z'),V5=c('l', 'm','n'), stringsAsFactors=FALSE)
##  V1 V2 V3 V4 V5
##1  1 10  a  x  l
##2  2 11  b  y  m
##3  3 12  c  z  n
Run Code Online (Sandbox Code Playgroud)

在哪里V1V2实际上numeric,其余的列不是因素,那么我们可以这样做:

library(dplyr)
y <- x %>% select_if(function(col) is.numeric(col) | 
                                   all(col == .$V4) | 
                                   all(col == .$V5))
##  V1 V2 V4 V5
##1  1 10  x  l
##2  2 11  y  m
##3  3 12  z  n
Run Code Online (Sandbox Code Playgroud)

不是说这是最好的事情,但它确实做你想要的.这里的问题是select_if期望它的函数返回对应于所有列的布尔向量.

另一种方法是使用select:

y <- x %>% select(which(sapply(.,class)=="numeric"),V4,V5)
##  V1 V2 V4 V5
##1  1 10  x  l
##2  2 11  y  m
##3  3 12  z  n
Run Code Online (Sandbox Code Playgroud)

这可能更好.


akr*_*run 5

map(来自purrr)的一种选择

library(purrr)
x %>%
     map2(names(x), ~.[is.numeric(.x)|.y != "V3"])  %>%
     Filter(length, .) %>% 
     bind_cols
 #     V1    V2    V4    V5
 #  <dbl> <dbl> <chr> <chr>
 #1     1    10     x     l
 #2     2    11     y     m
 #3     3    12     z     n
Run Code Online (Sandbox Code Playgroud)

或如@RoyalTS建议

x %>% 
    imap( ~ .[is.numeric(.x)|.y != "V3"]) %>%
    keep(~length(.x) > 0) %>%
    bind_cols
Run Code Online (Sandbox Code Playgroud)

由于数据集是data.table,子集的选项data.table将是

x[, sapply(x, is.numeric) | colnames(x) != "V3", with = FALSE]
#   V1 V2 V4 V5
#1:  1 10  x  l
#2:  2 11  y  m
#3:  3 12  z  n
Run Code Online (Sandbox Code Playgroud)

数据

x <- data.table(c(1,2,3),c(10,11,12),c('a','b','c'),c('x','y','z'), 
              c('l', 'm','n')) 
Run Code Online (Sandbox Code Playgroud)

注意:@nicola提到了为什么cbind不是必需的。因此,我们没有描述已经提出的相同问题。