2017-08-17 4 views
4

Ich verwende das data.table-Paket, um eine Liste der Funktionsschließungen in einem j-Ausdruck als Ausgabe von der approxfun-Funktion aus dem Statistikpaket zurückzugeben. Grundsätzlich möchte ich an jedem Datum eine Schließung haben, die es mir erlaubt, ein beliebiges yval basierend auf einem beliebigen xval zu berechnen, wie von approxfun bestimmt.Handhabung der Verschlüsse in data.table

approxfun ist jedoch nur gültig, wenn mindestens zwei eindeutige Werte von x an die Funktion übergeben wurden. Für den Fall, dass es nur einen eindeutigen Wert von x gibt, möchte ich eine Funktion zurückgeben, die den einen eindeutigen Wert von y zurückgibt.

In dem folgenden Code, führe ich diesen Schritt durch Überprüfen der .N Wert und eine andere Funktion zurückkehrt, je nachdem, ob oder ob nicht .N> 1 ist.

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)) 

Wenn die Funktion ‚afun‘ im Zusammenhang mit dem Ausdruck j Auswertung wird der korrekte Wert von ‚yval‘ gedruckt. Wenn ich jedoch nach der Tatsache zurück gehe, um die erste Funktion auszuwerten, ist das zurückgegebene yval das letzte yval in der Gruppe, die durch die Gruppierung 'nach' für die Funktion erstellt wurde, die nicht von approxfun erstellt wurde (alle von approxfun erstellten Schließungen) arbeiten wie erwartet).

Mein Verdacht ist, dass dies etwas zu tun hat, was ich mit fauler Bewertung vermisse. Ich habe den folgenden zusätzlichen Code mit der 'force' Funktion versucht, war aber nicht erfolgreich.

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)) 

Hat jemand anderes dieses Problem festgestellt? Ist es etwas, das ich mit Base R vermisse oder etwas, das ich mit data.table vermisse?

Vielen Dank im Voraus für die Hilfe

Antwort

5

Ja, typische data.table Referenz vs Kopie FAQ. Dies funktioniert wie erwartet:

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