我想编写一个以字符串作为输入的函数。确切地说,此输入表示概率分布,输出将是 5 个百分位数、平均值和 95 个百分位数作为向量或列表。
例如,如果我输入:“beta(0.2,0.3)” 我会得到:2.793073e-06 0.4 0.9992341
首先要做的事情是从字符串中读取分布,这可以使用正则表达式来完成:
dist <- gsub("[^A-z]","","beta(0.2,0.3)")
params <- gsub("[^0-9.,]","","beta(0.2,0.3)")
并且可以使用 strsplit 将参数放入数值向量中,例如
params <- as.numeric(unlist(strsplit(gsub("[^0-9.,]","","beta(0.2,0.3)"),split=",")))
现在,我需要声明一个均值函数(因为据我了解,R 中不存在随机分布均值函数)。对于 beta 发行版来说,这将是:
beta_mean <- function(alpha, beta) {
return(alpha / (alpha + beta))
}
我可以从 qbeta 函数获得百分位数,即:
qbeta(c(0.05,0.95), params[1], params[2])
既然我想处理许多不同的发行版,有没有比以下更优雅的方法:
meanvalue <- NA
percentiles <- NA
if(dist == "beta") {
meanvalue <- beta_mean(params[1], params[2])
percentiles <- qbeta(c(0.05,0.95), params[1], params[2])
} else if (dist == "gamma") {
meanvalue <- gamma_mean(params[1], params[2])
percentiles <- qgamma(c(0.05,0.95), params[1], params[2])
} #and so on and so on and so on...
return(c(percentiles[1],meanvalue,percentiles[2])
所以,我想做的是将发行版名称字符串(例如“beta”或“gamma”或其他)链接到相应的函数(DISTRIBUTIONNAME_mean 和 qDISTRIBUTIONNAME),这样我就不必使用那么长的 if-else -结构,包含太多(不必要的?)重复。
我怎样才能做到这一点?
我只能给出涵盖分位数的部分答案:
a_string <- "beta(0.2, 0.3)"
eval(parse(text = paste0("q", sub("\\(", "(c(0.05, 0.95), ", a_string))))
# 2.793073e-06 9.992341e-01
您可以尝试使用与此类似的方法(如果我正确理解问题,那么您仍然需要定义自己的“平均函数”): 如何在R中使用函数名的字符串来调用函数?
f1 <- match.fun("beta_mean")
f1(0.2,0.3)