[英]R function with functions as arguments, each with variable arguments
In answer to a question on Cross Validated , I wrote a simple function that used arbitrary quantile functions as its arguments 在回答关于Cross Validated的问题时 ,我写了一个简单的函数 ,它使用任意分位数函数作为其参数
etacor=function(rho=0,nsim=1e4,fx=qnorm,fy=qnorm){
#generate a bivariate correlated normal sample
x1=rnorm(nsim);x2=rnorm(nsim)
if (length(rho)==1){
y=pnorm(cbind(x1,rho*x1+sqrt((1-rho^2))*x2))
return(cor(fx(y[,1]),fy(y[,2])))
}
coeur=rho
rho2=sqrt(1-rho^2)
for (t in 1:length(rho)){
y=pnorm(cbind(x1,rho[t]*x1+rho2[t]*x2))
coeur[t]=cor(fx(y[,1]),fy(y[,2]))}
return(coeur)
}
However, both fx
and fy
may require their own parameters. 但是,
fx
和fy
可能需要自己的参数。 For instance, when fx=qchisq
or when fy=qgamma
. 例如,当
fx=qchisq
或fy=qgamma
。 As a default solution, in my implementation, I used 作为默认解决方案,在我的实现中,我使用过
fx=function(x) qchisq(x,df=3)
and 和
fy=function(x) qgamma(x,scale=.2)
but this is quite time consuming. 但这非常耗时。
For instance, 例如,
> rhos=seq(-1,1,.01)
> system.time(trancor<-etacor(rho=rhos,fx=qlnorm,fy=qexp))
utilisateur système écoulé
0.834 0.001 0.834
versus 与
> system.time(trancor<-etacor(rho=rhos,fx=qlnorm,fy=function(x) qchisq(x,df=3)))
utilisateur système écoulé
8.673 0.006 8.675
An illustration of my comment above: 以上评论的说明:
etacor1 <- function(rho = 0,
nsim = 1e4,
fx = qnorm,
fy = qnorm,
fx.args = formals(fx),
fy.args = formals(fy)){
#generate a bivariate correlated normal sample
x1 <- rnorm(nsim)
x2 <- rnorm(nsim)
fx.arg1 <- names(formals(fx))[1]
fy.arg1 <- names(formals(fy))[1]
if (length(rho) == 1){
y <- pnorm(cbind(x1, rho * x1 + sqrt((1 - rho^2)) * x2))
fx.args[[fx.arg1]] <- y[,1]
fy.args[[fy.arg1]] <- y[,2]
return(cor(do.call(fx,as.list(fx.args)),
do.call(fy,as.list(fy.args))))
}
coeur <- rho
rho2 <- sqrt(1 - rho^2)
for (t in 1:length(rho)){
y <- pnorm(cbind(x1,rho[t]*x1+rho2[t]*x2))
fx.args[[fx.arg1]] <- y[,1]
fy.args[[fy.arg1]] <- y[,2]
coeur[t] <- cor(do.call(fx,as.list(fx.args)),
do.call(fy,as.list(fy.args)))
}
return(coeur)
}
I am displeased with the apparent necessity of as.list
. 我对
as.list
的明显必要性感到不满。 I feel like I should know why that is, but it is escaping me at the moment. 我觉得我应该知道为什么会这样,但此刻它正在逃避我。
In using this function, it should not be necessary to pass in all arguments, but you do need to make sure any list you pass to fx.args
or fy.args
is named. 在使用此函数时,不必传入所有参数,但您需要确保传递给
fx.args
或fy.args
任何列表fy.args
命名。
Thanks for the comments and answer! 感谢您的评论和回答! I fear the core issue is that, as pointed out by joran and Mr Flick , some quantile functions are much slower to execute than others:
我担心核心问题是,正如joran和Flick先生所指出的,一些分位数函数的执行速度比其他函数慢得多:
> system.time(etacor(rhos,fx=function(x) qexp(x)))
utilisateur système écoulé
1.182 0.000 1.182
> system.time(etacor(rhos,fx=qexp))
utilisateur système écoulé
1.238 0.000 1.239
versus 与
> system.time(etacor(rhos,fx=function(x) qchisq(x,df=3)))
utilisateur système écoulé
4.955 0.000 4.951
> system.time(etacor(rhos,fx=function(x) qgamma(x,sha=.3)))
utilisateur système écoulé
4.316 0.000 4.314
So in the end using the definition of the function when it requires parameters does seem as a straightforward and easy solution. 所以最后在需要参数时使用函数的定义似乎是一个简单易行的解决方案。 Thanks for all of your inputs.
感谢您的所有投入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.