2013-08-06 51 views
0

我正在嘗試最大化爲數據框中的每一行創建的函數。當我使用應用程序時它工作正常,但是當我進入pApply時它不起作用。我不明白爲什麼。R - parApply無法使用optim或optimx評估函數/查找參數

下面是函數(估計半方差):

VB04 <- function(x) { 
    #the argument is a vector of 2 parameters, the first is x, the second lambda 

    ####I first define the function little f 
    ff <- function(z) { 
    ifelse (z <= x[2]*strike, return(x[1]), return(x[1]*(strike - z)/(strike*(1-x[2])))) 
    } 
    ####I then estimate the expected payoff of the contract 
    require(pracma) 
    require(np) 
    profit <- quadgk(function(y) { 
    #estimate the density 
    #Here since I have estimated the weather index overall, I will look at the entire distribution 
    density.pt <- npudens(bws = npudensbw(dat = as.data.frame(data.stations$weather_ind[ 
    which(data.stations$census_fips == census & data.stations$year < year_ext)]), 
             ckertype="epanechnikov", ckerorder=4), 
         tdat = as.data.frame(data.stations$weather_ind[ 
         which(data.stations$year < year_ext)]), 
         edat = as.data.frame(y)) 
    #return the value of the expected profit 
    return(ff(y)*density.pt$dens) 
}, a = 0, b = strike) 

##I now create a function that estimates the max 
#I do this county by county, to get the best contract in each case. 
#Only the density is estimated in common. 
#first element of the max argument 
max.arg <- sapply(-data.stations$yield[which(data.stations$census_fips == census 
               & data.stations$year < year_ext)] - 
       sapply(data.stations$weather_ind[which(data.stations$census_fips == census 
                 & data.stations$year < year_ext)], ff), 
       function(x) x + yield_avg + profit[[1]]) 
#add a second column of zeroes 
max.arg <- cbind(max.arg, 0) 
#Take the max 
max.arg <- apply(max.arg, 1, max) 
#Return the final value, the sum of squares 
return(sum(max.arg^2)) 
} 

我想將它應用到數據幀的每一行。以下是第一行:

test[1:10,] 
    census_fips yield_avg strike 
1  17143 161.8571 161.8571 
2  17201 139.4286 139.4286 
3  18003 147.4857 147.4857 
4  18103 150.1571 150.1571 
5  18105 137.8000 137.8000 
6  18157 157.8714 157.8714 
7  18163 149.5857 149.5857 
8  19013 168.4286 168.4286 
9  19033 163.9286 163.9286 
10  19045 161.2286 161.2286 

內parApply優化是這樣的:

library(foreach) 
library(doParallel) 
cl <- makeCluster(3) # My computer has 4 cores 
registerDoParallel(cl) 

clusterExport(cl=cl, varlist=c("VB04")) 

tempres <- parApply(cl=cl, X=test, MARGIN=1, FUN=function(x) { 
    strike <- x[3] #prepare the parameters 
    yield_avg <- x[2] 
    census <- x[1] 
    require(optimx) 
    minopt <- optimx(par=c(1,0.5), fn = VB04, lower=c(0,0), 
       upper=c(Inf,1), method="L-BFGS-B") 
    return(cbind(minopt$fvalues[[1]],minopt$par[[1]]) 
}) 

隨着optimx我得到的錯誤:「在初始參數無法計算功能的」完成後 優化工作正常對於任何行。它也適用於申請。 當我嘗試優化,而不是優化,我得到一個不同的錯誤:「對象'罷工'沒有找到」

我真的很感激任何幫助。我不確定是否問題是參數不傳遞(即使它們是在parApply內部定義的),或其他。我找不到如何修復它。

感謝,

編輯: 忘了把代碼調用集羣和傳遞功能的集羣。我已將它添加到上面

+2

你的問題只能包含必要的細節。嘗試制定簡明扼要的問題以便更好地理解。 –

回答

1

代碼中的一個問題是,諸如「strike」,「yield_avg」和「census」之類的變量不在VB04的範圍內,因爲它們是工作函數中的局部變量。您也可以通過在該函數中定義VB04來解決該問題。這將解決範圍問題,並且您也不必導出VB04

這是你的代碼的一個可笑的精簡版本,說明了這一點:

library(parallel) 
cl <- makePSOCKcluster(3) 
test <- matrix(1:4, 2) 
tempres <- parApply(cl, test, 1, function(x) { 
    VB04 <- function() { 
    strike * yield_avg 
    } 
    strike <- x[1] 
    yield_avg <- x[2] 
    VB04() 
}) 

optimoptimx提供一種方式來傳遞附加參數的功能,這可能是一個更好的解決方案。

+0

謝謝。在看到你的答案之前,我直接在optimx中使用傳遞參數。由於我有很多元素可以通過,所以它看起來更快。 – Olivier