R 在嵌套函数中传递参数和默认参数

R 在嵌套函数中传递参数和默认参数,r,scope,nested,parameter-passing,evaluation,R,Scope,Nested,Parameter Passing,Evaluation,我有一个函数,x_pdf,用来计算x*dfun(x | params),其中dfun是一个概率密度函数,params是一个命名参数列表。它是在另一个函数int\u pdf中定义的,该函数应该在指定的边界之间集成x\u pdf: int_pdf <- function(lb = 0, ub = Inf, dfun, params){ x_pdf <- function(X, dfun, params){X * do.call(function(X){dfun(x=X)}, para

我有一个函数,
x_pdf
,用来计算x*dfun(x | params),其中dfun是一个概率密度函数,params是一个命名参数列表。它是在另一个函数
int\u pdf
中定义的,该函数应该在指定的边界之间集成
x\u pdf

int_pdf <- function(lb = 0, ub = Inf, dfun, params){
  x_pdf <- function(X, dfun, params){X * do.call(function(X){dfun(x=X)}, params)}
    out <- integrate(f = x_pdf, lower=lb, upper=ub, subdivisions = 100L)
  out
}
当我按如下方式运行函数时:

GB2_params   <-  list(shape1 = 3.652, scale = 65797, shape2 = 0.3, shape3 = 0.8356)
int_gb2(params = GB2_params)

我已经花了好几个小时来调整它,并且我已经生成了许多可选的错误消息,但是总是关于缺少的x、x或参数。

这里似乎有两个问题,都与传递参数有关:第一个问题传递的参数太多,第二个问题传递的参数太少

首先,在您的
x_pdf
定义中,您使用了一个匿名函数,该函数只接受一个参数(
function(x){dfun(x=x)}
),但您还试图通过
do.call
将其他参数(参数列表)传递给所述匿名函数,这将引发一个错误。该部分应改为如下所示:

do.call(dfun, c(list(x = X), params))
现在,您已经将
x_pdf
定义为需要3个参数:
x
dfun
params
;但是,当您使用
integrate
调用
xpdf
时,您没有传递
dfun
params
参数,这将再次抛出错误。您也可以通过传递
dfun
params
来绕过这个问题:

integrate(f = x_pdf, lower=lb, upper=ub, subdivisions = 100L, dfun, params)
但也许更简洁的解决方案是从
x_pdf
的定义中删除附加参数(因为
dfun
params
已在封闭环境中定义),以获得更简洁的结果:

int_pdf <- function(lb = 0, ub = Inf, dfun, params){
  x_pdf <- function(X) X * do.call(dfun, c(list(x = X), params))
  integrate(f = x_pdf, lower = lb, upper = ub, subdivisions = 100L)
}
哦。示例参数是否缺少
scale
参数中的小数点

GB2_params$scale <- 6.5797
int_gb2(params = GB2_params)
#> 4.800761 with absolute error < 0.00015
由(v0.2.0)于2018年2月17日创建

如果你读过这么多,你可能也会喜欢哈德利·维克汉姆的作品


更多额外比特 @andrewH我从您的评论中了解到,您可能希望找到截断分布的平均值,例如,找到分布部分高于整个分布平均值的平均值

要做到这一点,仅仅将第一时刻的被积函数从平均值向上积分是不够的:你还必须在被积函数中重新缩放PDF,使其在截断后再次成为一个合适的PDF(如果你愿意的话,用“hand wave-y”修辞格弥补丢失的概率质量)。您可以通过将原始PDF的积分除以截断PDF的支持度来实现这一点

以下代码可以更好地传达我的意思:

库(purrr)
图书馆(GB2)

查找质量可能
积分(f=x\u pdf,下=lb,上=ub,参数,细分=100L)
。您对
integrate
的调用没有将
params
传递给被积函数。很抱歉,它必须是一个命名参数,
out@andrewH您能证明
int\u pdf
在直接调用时与
GB2\u params
一起工作吗这是一个很好的答案,我将接受它,但我非常感谢您对以下内容的思考:GB2软件包还提供了用于“中庸”和其他时刻的功能。我的参数应该可以得出1997年美国家庭收入的粗略近似值。使用矩函数:do.call(矩.gb2,c(k=0,gb2_参数))=1,do.call(矩.gb2,c(k=1,gb2_参数))=48007.61,还存在第二和第三矩;第四个不是。在平均值周围的单尾积分上运行您的修订版本,两者都存在,但上尾有一个不可能的值:33320,低于lb。令人费解。只是要清楚,您指的是计算
find_-mean(dgb2,lb=0,ub=48007.61,params=GB2_-params)=14687
find_-mean(dgb2,lb=48007.61,params=GB2_-params)=33320
?如果是这样,那么这就很有意义了:因为计算这两个积分基本上只是将完整的0到
Inf
积分划分为均值以下和均值以上的部分,因此积分之和必须等于均值。(正如
find_-mean(dgb2,0,Inf,…)
会给出平均值)我在答案的主体部分进一步大声思考。我是否遵循了你的要求?是的,那就是你评论中的参数与我使用的参数相同。。
int_pdf <- function(lb = 0, ub = Inf, dfun, params){
  x_pdf <- function(X) X * do.call(dfun, c(list(x = X), params))
  integrate(f = x_pdf, lower = lb, upper = ub, subdivisions = 100L)
}
GB2_params <- list(shape1 = 3.652, scale = 65797, shape2 = 0.3, shape3 = 0.8356)
int_gb2(params = GB2_params)
#> Error in integrate(f = x_pdf, lower = lb, upper = ub, subdivisions = 100L):
#>   the integral is probably divergent
GB2_params$scale <- 6.5797
int_gb2(params = GB2_params)
#> 4.800761 with absolute error < 0.00015