2017-12-18 4 views
1

Nach einem Beispiel in der Dokumentation dplyr::case_when() gegeben:Auswertung in dplyr :: case_when()

x <- 1:50 
case_when(x %% 35 == 0 ~ "fizz buzz", 
      x %% 5 == 0 ~ "fizz", 
      x %% 7 == 0 ~ "buzz", 
      TRUE ~ as.character(x)) 

Ich gehe davon aus, dass die Zahl 35 wird "buzz" produzieren, aber es produziert "fizz buzz"

Meine Argumentation ist, dass case_when() auswertet Alle Anweisungen eins nach dem anderen, unabhängig davon, ob eine vorherige wahr ist oder nicht (da TRUE ~ as.character(x) die letzte ist) und 35 %% 7 ist offensichtlich 0.

Was fehlt mir?

+4

Die Anweisungen werden der Reihe nach ausgewertet, und alles, was mit der ersten Anweisung übereinstimmt, erhält das erste Ergebnis und wird von späteren Ergebnissen nicht überschrieben. – Marius

+0

Ich bin immer noch verwirrt, warum diese letzte Anweisung TRUE ~ as.character (x) ausgewertet wird. – tictocchoc

+2

Es gibt "x" -Werte, die nicht durch 35, 5 oder 7 teilbar sind - es bleiben also noch Werte übrig, nachdem die ersten 3 Anweisungen behandelt wurden. Wenn Sie immer noch verwirrt sind, können Sie versuchen, genauer zu erklären, warum Sie denken, dass etwas anderes passieren sollte? – Marius

Antwort

1

case_when() wertet alle Aussagen einzeln unabhängig davon, ob eine vorherige wahr ist oder nicht (da es tut TRUE ausgewertet ~ as.character (x), die die letzte ist)

Diese ist irreführend, die Ausgabe von case_when() basiert auf der ersten Aussage, die wahr ist.

TRUE ~ as.character(x) bedeutet, dass, wenn x nicht durch 5 oder 7 teilbar ist, x als String zurückgegeben wird, dh für x = 5 wird "5" zurückgegeben. Wenn 0 durch 5 oder 7 teilbar ist, wertet casewhen() nachfolgende Fälle nicht aus. "Fizz" und "Buzz" sind nicht an as.character(x) übergeben und sie müssen nicht sein, weil sie bereits Zeichenfolgen sind.

+0

Sie haben Recht, dass "case_when" den Wert aus dem ersten wahren Fall nimmt, aber tatsächlich werden nachfolgende Fälle immer noch ausgewertet, wie man sehen kann, wenn sie Nebenwirkungen haben. ZB, Dies wird '" foo "' zurückgeben, aber Sie erhalten immer noch die Warnung aus dem zweiten Fall: 'case_when (TRUE ~" foo ", TRUE ~ Warnung (" bar "))' –

+0

Ähnlich wird dies '2' zurückgeben , aber danach ist x '3', weil es zweimal inkrementiert wurde: 'x <- 1; case_when (WAHR ~ (x <- x + 1), WAHR ~ (x <- x + 1)) '. (Um es klar zu sagen, ich empfehle nicht, solche Nebenwirkungen im Code zu verwenden - es ist nur ein Beispiel.) –

+0

@TimGoodman Danke, das ist ein guter Punkt und ich hätte es wissen müssen. Ich werde oft dadurch erwischt, dass ich TRUE ~ NA anstelle von NA_ [class] _ setze, obwohl ich in Fällen, in denen ich dachte, dass TRUE ~ nie ausgewertet wurde, einen Fehler erhalten habe, bin ich nicht zu den Punkten gekommen. – bmrn