将select_if与变量名和类型条件一起使用

时间:2018-12-18 16:42:04

标签: r dplyr

关于在多种情况下使用dplyr的select_if的文章很多。但是,无论如何,到目前为止,is.factor和变量名的选择对我来说都行不通。

最终,我想在df / tibble中选择所有因素,并按名称排除某些变量。

示例:

df <- tibble(A = factor(c(0,1,0,1)), 
             B = factor(c("Yes","No","Yes","No")), 
             C = c(1,2,3,4))

各种尝试:

尝试1

df %>%
  select_if(function(col) is.factor(col) & !str_detect(names(col), "A"))

Error in selected[[i]] <- .p(.tbl[[tibble_vars[[i]]]], ...) : replacement has length zero

尝试2

df %>%
      select_if(function(col) is.factor(col) & negate(str_detect(names(col)), "A"))

Error: Can't convert a logical vector to function Call `rlang::last_error()` to see a backtrace

尝试3

df %>%
  select_if(function(col) is.factor(col) && !str_detect(names(col), "A"))

Error: Only strings can be converted to symbols Call `rlang::last_error()` to see a backtrace

尝试4

df %>%
  select_if(is.factor(.) && !str_detect(names(.), "A"))

Error in tbl_if_vars(.tbl, .predicate, caller_env(), .include_group_vars = TRUE) : length(.p) == length(tibble_vars) is not TRUE

与此同时,各个条件都可以正常工作:

> df %>%
+     select_if(is.factor)
# A tibble: 4 x 2
  A     B    
  <fct> <fct>
1 0     Yes  
2 1     No   
3 0     Yes  
4 1     No   

> df %>%
+     select_if(!str_detect(names(.), "A"))
# A tibble: 4 x 2
  B         c
  <fct> <dbl>
1 Yes       1
2 No        2
3 Yes       3
4 No        4

问题可能出在这里:

df %>%
  select_if(function(col) !str_detect(names(col), "A"))

Error in selected[[i]] <- .p(.tbl[[tibble_vars[[i]]]], ...) : replacement has length zero

但是,我几乎不知道如何解决此问题。

2 个答案:

答案 0 :(得分:0)

也许我遗漏了一些东西,但是有什么原因使您无法执行以下操作:

df <- tibble(A = factor(c(0,1,0,1)), 
         B = factor(c("Yes","No","Yes","No")), 
         C = c(1,2,3,4))


df %>% select_if(function(col) is.factor(col)) %>% select_if(!str_detect(names(.), "A"))

# A tibble: 4 x 1
B    
<fct>
1 Yes  
2 No   
3 Yes  
4 No   

答案 1 :(得分:0)

只是为了完整起见,不确定您是否可以接受,但是基数R可能会在这里为您节省一些痛苦(第一步,非常快):

df[, sapply(names(df), 
  function(coln, df) !grepl("A", coln) && is.factor(df[[coln]]), df = df),
  drop = FALSE]