2017-08-17 1 views
4

私はdataパッケージを使用して、j式の関数クロージャのリストを出力し、approxfun関数の出力をstatsパッケージから返します。基本的には、各日付で、私はapproxfunで決定される任意のxvalに基づいて任意のyvalを計算することができるクロージャを使用したいと思います。data.tableでのクロージャの処理

ただし、approxfunは、少なくとも2つの一意の値xが関数に渡されている場合にのみ有効です。 xのユニークな値が1つしかない場合、yの1つの一意の値を返す関数を返したいと思います。

以下のコードでは、.N> 1であるかどうかによって、.Nの値をチェックし、別の関数を返すことでこの手順を実行します。 j表現の文脈における「関数afun」機能を評価する際

library(data.table) 
set.seed(10) 
N <- 3 
x <- data.table(Date = Sys.Date() + rep(1:N, each = 3), xval = c(0, 30, 90), yval = rnorm(N * 3)) 
x <- x[-c(2:3), ] 

##interpolation happens correctly 
x2 <- x[order(Date, xval), { 
    if(.N > 1){ 
     afun <- approxfun(xval, yval, rule = 1) 
    }else{ 
     afun <- function(v) yval 
    } 
    print(afun(30)) 
    list(Date, afun = list(afun)) 
}, by = Date] 

##evaluation does NOT happen correctly, the val used is the last... 
sapply(x2[, afun], do.call, args = list(v = 30)) 

、「yvalを指定」の正しい値が印刷されています。しかし、最初の関数を評価するために事実を調べると、返されるyvalは、approxfunによって作成されない関数の 'by'グループ化によって作成されたグループ内のの最後ののyvalです(すべてのクロージャはapproxfun期待通りに働く)。

私が疑問に思うのは、これが私が怠け者評価で紛失しているものと関係していることです。私は 'force'関数を使って以下の追加コードを試しましたが、失敗しました。

x3 <- x[order(Date, xval), { 
     if(.N > 1){ 
     afun <- approxfun(xval, yval, rule = 1) 
    }else{ 
     fn <- function(x){ 
      force(x) 
      function(v) x 
     } 
     afun <- fn(yval) 
    } 
    print(afun(30)) 
    list(Date, afun = list(afun)) 
}, by = Date] 

sapply(x3[, afun], do.call, args = list(v = 30)) 

他に誰かがこの問題を抱えていますか?それは私がbase Rで欠けているものか、data.tableで欠けているものか?コピーよくある質問VSヘルプ

答えて

5

はい、典型的なdata.table参照を事前に

感謝。期待どおりに動作します。

x2 <- x[order(Date, xval), { 
    if(.N > 1){ 
    afun <- approxfun(xval, yval, rule = 1) 
    }else{ 
    fn <- function(){ 
     #ensure the value is copied 
     x <- copy(yval) 
     function(v) x 
    } 
    afun <- fn() 
    } 
    print(afun(30)) 
    list(Date, afun = list(afun)) 
}, by = Date] 
#[1] 0.01874617 
#[1] 0.2945451 
#[1] -0.363676 

sapply(x2[, afun], do.call, args = list(v = 30)) 
#[1] 0.01874617 0.29454513 -0.36367602 
関連する問題