使用变量替换和 paste() 将参数分配给聚合

Assigning arguments to aggregate with variable substitution and paste()

我正在编写一个 Web 界面来对大型数据集进行统计。小部件将允许用户 select 变量和组。每个变量都与一种可以执行的统计相关联。该网页调用一个 R 脚本,该脚本设置适当的数据框以传递给“聚合”,然后传递给各种输出。这里的数据不相关,所以我没有包含它。

我的问题是“聚合”的灵活输入由于我无法弄清楚的原因而被轰炸:

group variable “grp”
str(grp)
'data.frame':   1573 obs. of  1 variable:
 $ Loc: Factor w/ 4 levels "ED","ICU","Trans",..: 1 1 1 1 1 1 1 1 1 4 ...

Time variable
TimeBase <- “year”

data
str(tmp)
'data.frame':   554 obs. of  4 variables:
$ Loc     : Factor w/ 4 levels "ED","ICU","Trans",..: 4 1 1 1 4 4 1 1 4 4 ...
$ year    : Factor w/ 7 levels "2011","2012",..: 1 1 1 1 1 1 1 1 1 1 ...
$ ActivLag: num  3 -2 0 1 17 210 19 -7 0 107 ...
$ ScanLag : num  80 12 5 8 159 255 28 109 11 111 ...

aggregate(formula(paste0(". ~", names(grp), " + ", TimeBase)), data = tmp, paste0(stvar), na.rm = TRUE, na.action = na.pass)

如果 stvar = “mean”,这工作正常,但如果 stvar = “sum”,它不以 na.rm 作为参数,它不起作用。所以,我尝试了以下方法:

statstrg <- ifelse(stvar %in% c("sum", "prop","frel", "median"), " na.action    = na.pass", " na.rm = TRUE, na.action = na.pass")
aggregate(formula(paste0(". ~", names(grp), " + ", TimeBase)), data = tmp,  paste0(stvar), paste0(statstrg)) 

这不起作用并给出以下错误:

Error in if (na.rm) x <- x[!is.na(x)] else if (any(is.na(x)))  return(x[FALSE][NA]) : 
argument is not interpretable as logical

即使

aggregate(formula(paste0(". ~", names(grp), " + ", TimeBase)), data = tmp, paste0(stvar), na.action = na.pass) 

对 stvar = “sum”有效。

对每个 na.rm 和 na.action = na.pass 使用条件字符串赋值和 paste(var) 不起作用,因为无法处理所需的逗号聚合以解析参数。我试过在 paste() 中传递各种参数组合,但聚合想要查看单个参数。那么任何人都可以指出一种可能更好的方法吗?谢谢

虽然可以使用字符串动态生成公式,但函数中的参数赋值不能从字符串构建,例如可选参数,aggregate() 中的 na.rmna.action,其默认值为 NULL.

考虑根据 stvar:

有条件地分配两个不同的 aggregate() 调用
if (stvar %in% c("sum", "prop", "frel", "median")) {
    aggdf <- aggregate(formula(paste0(". ~", names(grp), " + ", TimeBase)), data = tmp, 
                       FUN = stvar, na.action = na.pass)
} else {
    aggdf <- aggregate(formula(paste0(". ~", names(grp), " + ", TimeBase)), data = tmp, 
                       FUN = stvar, na.rm = TRUE, na.action = na.pass)
}

或者,将变量 st_narm 有条件地分配给 TRUENULL,这需要使用 if 而不是 ifelse 因为您不能将空对象分配给一个值(替换长度失败)。

if(stvar %in% c("sum", "prop","frel", "median")){
  st_narm <- NULL
} else {
  st_narm <- TRUE
}

aggdf <- aggregate(formula(paste0(". ~", names(grp), " + ", TimeBase)), data = tmp, 
                   FUN = stvar, na.rm = st_narm, na.action = na.pass)

谢谢你的好建议!问题已解决,但为了完整起见:

1) "aggregate" 不会将 sum() 作为参数,只有 "sum" 和 na.rm 是从 "aggregate" 传递的,而不是通过 sum() 和如果同时传递 sum 和 na.rm 会报错。

2) if-then st_narm <- NULL 方法仍然给我一个错误: Error in if (na.rm) x <- x[!is.na( x)] else if (any(is.na(x))) return(x[FALSE][NA]) : 参数的长度为零。所以没用。

3) 带有完整 "aggregate" 字符串的条件语句运行良好,尽管不知何故似乎不太优雅。但是,完成工作。

再次感谢。必须热爱开源社区!