[英]R function with functions as arguments, each with variable 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)
}
但是, 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
以上評論的說明:
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
任何列表fy.args
命名。
感謝您的評論和回答! 我擔心核心問題是,正如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
與
> 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
所以最后在需要參數時使用函數的定義似乎是一個簡單易行的解決方案。 感謝您的所有投入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.