base::formals 多选项参数 [R]

base::formals with multiple-option arguments [R]

我试图从函数 (randomForestSRC::rfsrc) 中提取所有参数及其默认选项,以将其集成到另一个函数中。这就是我正在做的事情:

> mydata <- source("https://pastebin.com/raw/bL8ZHvbt")$value
> myparams <- list(ntree = 500, seed = 333)
> time = "OS"
> event = "Death"

# prepare vars
> aux <- formals(randomForestSRC::rfsrc)[-c(1,2,32,35)] #delete arguments I gonna manually add
> diffs <- setdiff(names(aux), names(myparams))
> method.params <- c(myparams, aux[diffs])

# run function
> f <- as.formula(paste0("Surv(", time, ",", event, ") ~ ."))
> res <- do.call(randomForestSRC::rfsrc, c(list(formula = f, data = mydata), method.params))

Error in (function (formula, data, ntree = 1000, mtry = NULL, ytry = NULL,  : 
  object 'samptype' not found

我猜错误提示是因为 rfsrc 的参数格式:它不是单个值而是多个选项...尽管 只有一个 作为默认选项.

> aux$importance #default value for "importance" is "none"
c(FALSE, TRUE, "none", "permute", "random", "anti")

> str(aux)
List of 31
 $ ntree      : num 1000
 $ nodedepth  : NULL
 $ splitrule  : NULL
 $ nsplit     : num 10
 $ importance : language c(FALSE, TRUE, "none", "permute", "random", "anti")
 ...

我的问题是如何提取这个唯一的默认值而不是整个选项字符串?提前致谢。

这将允许您在与原始 rfsrc 具有相同环境的新函数中更改您试图设置为 500 和 333 的两个参数的默认值。 (你可以在原来的函数里做,但那样看起来更危险。)

library(randomForestSRC)
rfsrc2 <- rfsrc
environment(rfsrc2) <- environment(rfsrc)
params <- formals(rfsrc)
myparams <- list(ntree = 500, seed = 333)
params[c("ntree","seed")] <- myparams 
    # more generally could have been `params[names(myparams)]` on LHS
formals(rfsrc2) <- params

str(rfsrc2)
#-------
function (formula, data, ntree = 500, mtry = NULL, ytry = NULL, nodesize = NULL, nodedepth = NULL, splitrule = NULL, nsplit = 10, 
    importance = c(FALSE, TRUE, "none", "permute", "random", "anti"), block.size = if (any(is.element(as.character(importance), 
        c("none", "FALSE")))) NULL else 10, ensemble = c("all", "oob", "inbag"), bootstrap = c("by.root", "none", "by.user"), 
    samptype = c("swor", "swr"), samp = NULL, membership = FALSE, sampsize = if (samptype == "swor") function(x) {
        x * 0.632
    } else function(x) {
        x
    }, na.action = c("na.omit", "na.impute"), nimpute = 1, ntime, cause, proximity = FALSE, distance = FALSE, forest.wt = FALSE, 
    xvar.wt = NULL, yvar.wt = NULL, split.wt = NULL, case.wt = NULL, forest = TRUE, var.used = c(FALSE, "all.trees", "by.tree"), 
    split.depth = c(FALSE, "all.trees", "by.tree"), seed = 333, do.trace = FALSE, statistics = FALSE, ...)  

# test of "function"-ality
rfsrc2(formula=f, data=mydata)
                         Sample size: 100
                    Number of deaths: 11
                     Number of trees: 500
           Forest terminal node size: 15
       Average no. of terminal nodes: 4.464
No. of variables tried at each split: 3
              Total no. of variables: 6
       Resampling used to grow trees: swor
    Resample size used to grow trees: 63
                            Analysis: RSF
                              Family: surv
                      Splitting rule: logrank *random*
       Number of random split points: 10
                          Error rate: 58.9%

如果你想用 do.call 做到这一点,它可能是:

do.call( rfsrc2, list(formula=f, data=mydata) )

重要的是不要从形式列表中删除 formuladata...,因为当函数主体中的代码寻求评估他们。我很确定您不能使用 do.call 将它们粘贴回去(在删除它们之后)。您当然可以通过以下方式回避整个过程:

do.call( rfsrc, list(formula=f, data=mydata, ntree=500, seed=333) )

...但我知道你想要在函数本身之外的形式列表上进行手术的方法。