我想编写一个函数,它将创建并返回一组参数,以便在我创建的函数mySimulation
中使用。到目前为止,我基本上一直在做,例如,mySimulation(parm1 = 3, parm2 = 4)
。这现在不是最理想的,因为(1)在实际版本中,参数的数量变得难以处理,以及(2)我想跟踪产生我正在使用的不同模型的参数的不同组合。所以,我写了createParms
(下面显示的最低限度版本)来完成这个技巧。我的整个方法看起来很笨重。所有统计人员使用R,我确信有一种更标准的方式来处理我的问题......对吗?
createParms <- function(model = "default", ...) {
# Returns a list `parms` of parameters which will then be used in
# mySimultation(parms)
#
# Args:
# model: ["default" | "mymodel"] character string representation of a model
# with known parameters
# ...: parameters of the existing `model` to overwrite.
# if nothing is supplied then the model parameters will be left as is.
# passed variables must be named.
# e.g., `parm1 = 10, parm2 = 20` is good. `10, 20` is bad.
#
# Returns:
# parms: a list of parameters to be used in mySimulation(parms)
#
parms.names <- c("parm1", "parm2")
parms <- vector(mode = "list", length = length(parms.names))
names(parms) <- parms.names
overwrite <- list(...)
overwrite.names <- names(overwrite)
if (model == "default") {
parms$parm1 <- 0
parms$parm2 <- 0
} else if (model == "mymodel") {
parms$parm1 <- 1
parms$parm2 <- 2
}
if (length(overwrite) != 0) {
parms[overwrite.names] <- overwrite
}
return(parms)
}
答案 0 :(得分:2)
我想如果你知道每个模型使用的参数组合,那么最好创建一个模型名称和参数的数据框,如下所示
# create a data frame with model names and parameters
# NOTE: i am assuming all models have equal number of parameters
# if they are unequal, then store as list of models
model = c('default', 'mymodel');
parm1 = c(0.5, 0.75);
parm2 = c(1, 2);
models.df = data.frame(model, parm1, parm2)
现在,您可以通过将其作为参数传递给mySimulation函数来模拟任何模型。我使用了一个虚拟仿真示例,您可以用代码替换它。
# function to run simulation based on model name
mySimulation = function(model = 'default'){
# find row corresponding to model of interest
mod.row = match(model, models.df$model)
# extract parameters corresponding to model
parms = models.df[mod.row, -1]
# run dummy simulation of drawing normal random variables
sim.df = rnorm(100, mean = parms[,1], sd = parms[,2])
return(sim.df)
}
如果您现在想要一步完成所有模拟,可以使用优秀的plyr
包并调用
library(plyr)
sim.all = ldply(models.df$model, mySimulation)
如果您的每个模拟都返回不等数量的值,那么您可以使用函数llply
而不是ldply
。
如果您提供有关模拟返回值的更多信息以及模拟的详细信息,可以轻松调整此代码以获得所需内容。
让我知道这是否有效
答案 1 :(得分:1)
如果模拟函数总是使用相同的参数集,那么Ramnath将它们存储在数据框中的方法是最好的。对于mySimulation
的变量输入的更一般情况,您应该将每组输入存储在列表中 - 可能使用列表列表来运行多个模拟。
createParms
功能背后的想法看起来很合理;你可以稍微简化代码。
createParms <- function(model = "default", ...)
{
#default case
parms <- list(
parm1 = 0,
parm2 = 0
)
#other special cases
if(model == "mymodel")
{
parms <- within(parms,
{
parm1 <- 1
parm2 <- 2
})
}
#overwrite from ...
dots <- list(...)
parms[names(dots)] <- dots
parms
}
用例如
测试createParms()
createParms("mymodel")
createParms("mymodel", parm2 = 3)
do.call
可能会在运行模拟时派上用场,就像在
do.call(mySimulation, createParms())
编辑:do.call
为您做什么
如果您有parms <- createParms()
,那么
do.call(mySimulation, parms)
与
相同with(parms, mySimulation(parm1, parm2))
主要优点是您不需要拼出您传入mySimulation
的每个参数(或修改该函数以接受列表形式的参数)。