2015-04-23 5 views
5

Ich versuche, eine bedingte lead/lag Funktion in einem dplyr Rohr mit ifelse, aber einen Fehler zu erhalten. Mit dem gleichen Ansatz außerhalb der Pipe scheint es jedoch zu funktionieren. Was vermisse ich?R: dplyr Rohr bedingte Blei/Verzögerung mit ifelse mit unerwartetem Verhalten

require(dplyr) 

Daten:

test <- data.frame(a = c("b","b","b","b","b","b", 
         "m","m","m","m","m","m", 
         "s","s","s","s","s","s"), 
        b = replicate(1,n=18), 
        stringsAsFactors=F) 

dplyr Rohr:

test %>% 
    mutate(delta = ifelse(a == "s", b + lag(b, n = 2*6), 
         ifelse(a == "m", b + lag(b, n = 1*6), 0))) 

# Error: could not convert second argument to an integer. type=LANGSXP, length = 3 

Ohne das Rohr funktioniert es:

test$delta <- ifelse(test$a == "s", test$b + lag(test$b, n = 2*6), 
        ifelse(test$a == "m", test$b + lag(test$b, n = 1*6), 0)) 

ich einige Hinweise gefunden, dass es ein Problem war mit dplyr lead/lag in Kombination mit gruppierten Datenrahmen. Aber ich gruppiere mich hier nicht.

Versionsinfo: R 3.1.1 und dplyr_0.4.1.

Antwort

1

dplyr kann den Ausdruck nicht analysieren. Eine Lösung ist, um die Funktion zu definieren zuerst:

foo <- function(a, b) 
    ifelse(a=="s",b+lag(b,n=2*6), ifelse(a=="m",b+lag(b,n=1*6),0)) 
test %>% mutate(delta = foo(a,b)) 
4

Dies:

test %>% 
    mutate(delta = ifelse(a=="s",b+lag(b,n=12), 
          ifelse(a=="m",b+lag(b,n=6),0))) 

funktioniert. Dies bedeutet, dass Sie keine Ausdrücke in lag Argumente übergeben können.

+2

Wenn ja, warum 'ifelse (Test $ a == "s", test $ b + Verzögerung (Test $ b, n = 2 * 6), ifelse (test $ a == "m", test $ b + lag (test $ b, n = 1 * 6), 0)) "funktioniert? –

+2

es klingt wie ein Fehler von 'dplyr'. –

+0

Dies bezieht sich auf die Auswertung der Ausdrücke. In diesem Code werden alle Ausdrücke in der globalen Umgebung ausgewertet, im Fall dplyr findet die Auswertung in verschiedenen Umgebungen statt. Dies ist wahrscheinlich ein Fehler in dplyr. – mpiktas