字符串条件下的子集df

时间:2017-07-04 08:45:27

标签: r string eval subset

我希望在未知条件下对df进行分组(例如,在下面的示例中随机定义):

df <- data.frame(a=1:10, b = 10:1)
condition <- paste0(sample(letters[1:2],1), sample(c("<",">"),1), sample(1:10,1))

我可以用eval执行此操作,其中,vox populi不是最理想的:

subset(df, eval(parse(text=condition)))

是否有替代eval(parse)

4 个答案:

答案 0 :(得分:2)

如果变得更可行,稍微调整一下你的脚本:

condition  <- list(value1 = sample(letters[1:2], 1),
                   comp =   sample(c(`<`, `>`), 1)[[1]],
                   value2 = sample(1:10, 1))

subset(df, condition$comp(df[, condition$value1], condition$value2))

所以这取决于条件如何通过的限制。

(请注意,使用subset可能是一个坏主意)

答案 1 :(得分:1)

如果可以引入一些约束,例如数据框只有数字列,而且只有线性条件,那么您可以将条件决策制定为点积:

# a > b
condition.mat <- c(1, -1)
condition.const <- 0

# b > 4
# condition.mat <- c(0, 1)
# condition.const <- 4

dec <- as.matrix(df) %*% condition.mat - condition.const
sel <- dec > 0

print(df[sel,])

答案 2 :(得分:1)

基础subset的替代方案是来自filter的{​​{1}}函数:

dplyr

答案 3 :(得分:1)

只想一想。如果没有(令人讨厌的)“字符表达式”,还有其他方法可以使代码保持动态,例如:

df <- data.frame(a=1:10, b = 10:1)

mysubset <- function (f,x1,x2) {
  df[f(df[[x1]],x2),]
}

mycol <- sample(letters[1:2],1) 
myfun <- sample(c("<",">"),1)
mylimit <- sample(1:10,1)

mysubset(.Primitive(myfun),mycol,mylimit) # in my mind just as dynamic as eval-parse ..

mysubset(`<`,"a",4)