在回答a question on Cross Validated时,我写了a simple function使用任意分位数函数作为其参数
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)
}
但是,fx
和fy
都可能需要自己的参数。例如,fx=qchisq
或fy=qgamma
时。作为默认解决方案,在我的实现中,我使用了
fx=function(x) qchisq(x,df=3)
和
fy=function(x) qgamma(x,scale=.2)
但这非常耗时。
例如,
> 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
与
> 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
答案 0 :(得分:3)
上述评论的说明:
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)
}
我对as.list
的明显必要性感到不满。我觉得我应该知道为什么会这样,但此刻它正在逃避我。
在使用此功能时,不必传递所有参数,但您需要确保传递给fx.args
或fy.args
的任何列表都已命名。
答案 1 :(得分:1)
感谢您的评论和回答!我担心核心问题是,正如joran和Mr 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
与
> 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
所以最后在需要参数时使用函数的定义似乎是一个简单易行的解决方案。感谢您的所有投入。