如何将字符串作为参数传递给`do.call`命令?

时间:2014-08-06 12:15:44

标签: r

如何将字符串(例如"na.rm=TRUE")作为参数传递给do.call命令?

例如,这可以按预期工作:

> do.call(mean, list(1:10, na.rm=TRUE))
[1] 5.5

但是如果我将参数na.rm=TRUE作为字符串:"na.rm=TRUE"怎么办?如果我尝试以下操作,则会失败:

> do.call(mean, list(1:10, "na.rm=TRUE"))
Error in mean.default(1:10, "na.rm=TRUE") : 
  'trim' must be numeric of length one
> do.call(mean, list(1:10, na.rm="na.rm=TRUE"))
Error in if (na.rm) x <- x[!is.na(x)] : 
  argument is not interpretable as logical

所以给定一个字符串形式的参数("na.rm=TRUE"),如何在do.call命令中使用它?

为了提供更多背景信息,相关的GUI适用于dcast中的reshape2。用户可以在两个单独的框中输入:

  • 功能名称
    • 说,user_fun <- "mean",然后传递给dcast(fun.aggregate=get(user_fun))
  • 功能args
    • user_ags <- "na.rm=TRUE",然后通过dcast(...)传递给do.call

所以在一天结束时,它看起来像是:

do.call(dcast, list(data_set, form, 
                     fun.aggregate=user_fun, user_ags))

正如您所看到的,我将user_ags纳入do.call时遇到问题。据我所知,user_ags可以包含任意数量的参数和任何可能的类型(例如,user_ags <- "na.rm=TRUE, other.arg='both', yet.another=NULL")。

所以我正在寻找一种解析这种字符串的通用方法,例如eval(parse(text=""))方法或类似方法。我尝试了evalparsedeparsesubstitute的各种组合,但都无济于事。

2 个答案:

答案 0 :(得分:4)

这是一个不使用eval但是将参数包装在假函数调用中并使用parse来提取它们的方法

#sample function
myfun<-function(...) {
    print(list(...))
}

strparam <- "na.rm=TRUE, plot=F, age=15"

params <- as.list(parse(text=paste0("f(", strparam , ")"))[[1]])[-1]

do.call(myfun,params)

答案 1 :(得分:1)

如果输入格式符合某些规范,您可以随时进行字符串处理:

fun <- "mean"
args <- "trim=0.1, na.rm=FALSE"
args <- strsplit(args, ",", fixed=TRUE)
args <- strsplit(args[[1]], "=", fixed=TRUE)
names(args) <- gsub(" ", "", sapply(args, "[", 1), fixed=TRUE)
args <- lapply(args, "[", -1)
args <- lapply(args, type.convert)

do.call(get(fun), c(list(1:10), args))
#[1] 5.5
mean(1:10, trim=0.1, na.rm=FALSE)
#[1] 5.5 

但允许任意输入总是危险的。