web-dev-qa-db-ja.com

複数の条件を持つR dplyr select_if

すべての数値変数といくつかの変数を名前で選択したいと思います。 select_ifを使用して数値変数を取得し、名前で選択して取得しましたが、2つを1つのステートメントに結合できません

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

私の結果は:

V1 V2 V4 V5
1 10  x l
2 11  y m
3 12  z n

私はこれを試しましたが、うまくいきません

y = x %>%
select_if(is.numeric, V4, V5)
10
David

データフレームがある場合、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

どこ V1およびV2は実際には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

これが最善の方法であると言っているわけではありませんが、それはあなたが望むことをします。ここでの問題はselect_ifは、その関数がすべての列に対応するブールベクトルを返すことを期待しています。

もう1つの方法は、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

それはおそらくより良いです。

15
aichao

mapの1つのオプション(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

または@RoyalTSが示唆したように

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

データセットは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

データ

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

注:@nicolaは、cbindが不要な理由について言及しました。したがって、すでに提起されたのと同じ問題については説明しません。

5
akrun