2017-11-09 2 views
0

私は、任意のpdf関数(例:pnorm、punif、pbinomなど)の二次誤差を最小にするパラメータを見つけるためにRに関数を実装しています。設計は、densit機能(例えば、meanおよびsdpnorm)から、確率、経験的分位数、関数名(densit)、およびパラメータ名のリスト(params)をユーザが提供するような設計である。インスタンスに対して、q1q2、そして-1.644854に等しいq3、0、及び1.644854、及びp1p2、及び0.05に等しいp3、0.5、0.95するためのもので、関数は、それぞれほぼ0と1 meansdを回収すべきです。optim()内の式の評価中のエラー

optimにそのような式を与え、後者は最適化中に式を評価する関数(内部でquadraticFunと呼ばれる)をとることです。しかし、私はoptimを推定のためのそのような式に作用させることはできません。関数は、このです:

> findParams(q1 = -1.644854, q2 = 0, q3 = 1.644854, densit = pnorm, params = list("mean", "sd")) 
Error in pnorm(-1.644854, mean, sd) : 
    Non-numeric argument to mathematical function 

それは表現と思われる:次の例に

fun <- function(p1 = 0.05, p2 = 0.50, p3 = 0.95, q1, q2, q3, output = "complete", densit, params) { 
    densit <- substitute(densit) 
    params <- sapply(params, as.name) 
    densiCall1 <- as.call(c(as.list(densit), as.list(q1), params)) 
    densiCall2 <- as.call(c(as.list(densit), as.list(q2), params)) 
    densiCall3 <- as.call(c(as.list(densit), as.list(q3), params)) 
    quadratEq <- substitute((densiCall1 - p1)^2 + 
          (densiCall2 - p2)^2 + 
          (densiCall3 - p3)^2) 
    quadraticFun <- function(params) { 
     eval(quadratEq) 
    }  
    initVals <- rep(1, times = length(params)) 
    res <- optim(initVals, quadraticFun) # ERROR SOMEWHERE AROUND HERE... 
    # if output is set to "complete", return the whole res object, otherwise, return just the parameters 
    if (output == "parameters") { 
     return(res$par) 
    } 
    return(res) 
} 

デバッグは、具体的に次のメッセージを含むquadraticFunの評価中に、エラーがコールoptim(initVals, quadraticFun)中に現れることを示しています最適化する関数の引数の代わりに評価する記号として、meanasという文字通り解釈されます。

この問題の解決に役立つヒントがあれば、事前にお知らせください。

答えて

1

機能quadraticFunは、densiCall1機能に正しくparamsパラメータを渡していないため、機能しませんでした。

評価が必要な呼び出しが1つしかないように、コードを少し変更しました。これは処理が簡単です。今度はdensitが文字列ですが、これはあなたが変更できると確信しています。

findParams <- function(q = c(-1.644854, 0, 1.644854), 
     p = c(0.05, 0.50, 0.95), output = "complete", densit="pnorm", 
     params = c("mean", "sd")) { 
    l <- length(params) 
    cl <- vector("list", 2 + length(params)) 
    cl[[1]] <- as.name(densit) 
    cl[[2]] <- q 
    names(cl) <- c(NA, "q", params) 
    mode(cl) <- "call" 
    quadraticFun <- function(x) { 
     cl[3:(l+2)] <- x 
     res <- eval(cl) 
     sum((res - p)^2) 
    }  
    initVals <- rep(1, times = l) 
    res <- optim(initVals, quadraticFun) 
    if (output == "parameters") { 
     return(res$par) 
    } 
    return(res) 
} 

そして、動作しているようです:コールとベクトル化操作の実装の改善を構築するためのより良い方法を指摘して

findParams() 
$par 
[1] 0.0001065349 1.0001052494 

$value 
[1] 2.682477e-09 

$counts 
function gradient 
     67  NA 

$convergence 
[1] 0 

$message 
NULL 
+0

おかげでここ は、私が思い付いた機能です。あなたの答えは問題を解決し、洞察力があった。 – gaballench