2016-04-08 14 views
2

data.frameをルールのリストで動的にサブセット化する必要があります。例えば、これらのもののようなルール:ルールのリストでdata.frameを動的にサブセット化

  • df[col1] == 's'
  • df[col2] == 'z'
  • df[col3] == 'a' | df[col3] == 'b' | df[col3] == 'c'

静的に、私は希望:

df <- df[df[col1] == 's' 
     & df[col2] == 'z' 
     & (df[col3] == 'a' | df[col3] == 'b' | df[col3] == 'c'), ] 

どのように私は同じdinamicallyを達成できます私はすべてのルールを格納するlist ES:

私はこれをしたいと思っ
rules <- list(col1 = c('s'), col2 = c('z'), col3 = c('a', 'b', 'c')) 

df <- magic(df, rules) 

はその可能のようなものですか?

答えて

4

あまり一般化されていません - それぞれの要素はandとなり、各要素の要素はそれぞれorとなりますが、それはあなたの質問です。

df <- data.frame(col1 = c('a','s','x'), 
       col2 = c('a','z','s'), 
       col3 = c('a','c','b'), 
       stringsAsFactors = FALSE) 

df[with(df, col1 == 's' 
     & col2 == 'z' 
     & (col3 == 'a' | col3 == 'b' | col3 == 'c')), ] 

# col1 col2 col3 
# 2 s z c 


rules <- list(col1 = c('s'), col2 = c('z'), col3 = c('a', 'b', 'c')) 


df[Reduce(`&`, Map(`%in%`, df, rules)), ] 

# col1 col2 col3 
# 2 s z c 

magic

magic <- function(data, rules) { 
    data[Reduce(`&`, Map(`%in%`, data, rules)), ] 
} 

magic(df, rules) 
# col1 col2 col3 
# 2 s z c 

編集 - バージョン2

この1つのルールなし1)列のために働く及び/又は2)列

の正確な順序ではないルールべき
magic <- function(data, rules) { 
    rules <- rules[names(data)] 
    idx <- Map(`%in%`, data, rules) 
    idx[is.na(names(rules))] <- list(rep(TRUE, nrow(data))) 
    data[Reduce(`&`, idx), ] 
} 

df <- data.frame(col1 = c('a','s','x'), 
       col2 = c('a','z','s'), 
       colx = rnorm(3), 
       col3 = c('a','c','b'), 
       stringsAsFactors = FALSE) 


rules <- list(col2 = c('z'), col1 = c('s'), col3 = c('a', 'b', 'c')) 
magic(df, rules) 
# col1 col2  colx col3 
# 2 s z -1.374339 c 

さらに多くのテスト

magic(mtcars, list(gear = 4, carb = 1:2)) 

#     mpg cyl disp hp drat wt qsec vs am gear carb 
# Datsun 710  22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 
# Merc 240D  24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 
# Merc 230  22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 
# Fiat 128  32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 
# Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 
# Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 
# Fiat X1-9  27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 
# Volvo 142E  21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2 
+1

おい...それは...すごい!今私はそれを理解する必要がありますが、それは私が必要とするものです。本当にありがとう、私には、あなたは間違いなくRの教祖です! – thelawnmowerman

+0

@thelawnmowerman編集を参照してください、私はこれがもう少し堅牢だと思います。興味深い質問をしてくれてありがとう! – rawr

+0

間違いなく、より良い! – thelawnmowerman