将表达式连接到数据帧的子集

时间:2011-04-03 17:33:09

标签: r subset

我正在尝试创建一个函数来计算子集化数据帧中列的平均值。这里的诀窍是我总是希望有一些子集条件,然后可以选择将更多条件传递给函数以进一步对数据帧进行子集化。

假设我的数据如下所示:

dat <- data.frame(var1 = rep(letters, 26), var2 = rep(letters, each = 26), var3 = runif(26^2))

head(dat)
  var1 var2      var3
1    a    a 0.7506109
2    b    a 0.7763748
3    c    a 0.6014976
4    d    a 0.6229010
5    e    a 0.5648263
6    f    a 0.5184999

我希望能够使用所有函数调用中的第一个条件来执行下面显示的子集,第二个是可以随每个函数调用更改的内容。另外,第二个子集条件可以是其他变量(我使用单个变量var2,用于简约,但条件可能涉及多个变量)。

subset(dat, var1 %in% c('a', 'b', 'c') & var2 %in% c('a', 'b'))
   var1 var2      var3
1     a    a 0.7506109
2     b    a 0.7763748
3     c    a 0.6014976
27    a    b 0.7322357
28    b    b 0.4593551
29    c    b 0.2951004

我的示例函数和函数调用类似于:

getMean <- function(expr) {  
  return(with(subset(dat, var1 %in% c('a', 'b', 'c') eval(expr)), mean(var3)))  
}
getMean(expression(& var2 %in% c('a', 'b')))

另一种看法可能如下:

getMean(expression(& var4 < 6 & var5 > 10))

非常感谢任何帮助。


编辑:在Wojciech Sobala的帮助下,我提出了以下功能,这使我可以选择传递0个或更多条件。

getMean <- function(expr = NULL) {
  sub <- if(is.null(expr)) { expression(var1 %in% c('a', 'b', 'c'))
  } else expression(var1 %in% c('a', 'b', 'c') & eval(expr))
  return(with(subset(dat, eval(sub)), mean(var3)))
}
getMean()
getMean(expression(var2 %in% c('a', 'b')))

2 个答案:

答案 0 :(得分:1)

这就是我接近它的方法。函数getMean使用R的方便的默认参数设置:

getMean <- function(x, subset_var1, subset_var2=unique(x$var2)){
    xs <- subset(x, x$var1 %in% subset_var1 & x$var2 %in% subset_var2)

    mean(xs$var3)
}

getMean(dat, c('a', 'b', 'c'))
[1] 0.4762141

getMean(dat, c('a', 'b', 'c'), c('a', 'b'))
[1] 0.3814149

答案 1 :(得分:1)

可以使用默认的expr = TRUE进行简化。

getMean <- function(expr = TRUE) {
  return(with(subset(dat, var1 %in% c('a', 'b', 'c') & eval(expr)), mean(var3)))
}