2017-12-18 287 views
1

dplyr::case_when()文檔中給出的例子:評價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)) 

我想到的是人數35會產生"buzz"但它產生"fizz buzz"

我的理由是,case_when()評估板無論前一個是否爲真(因爲它確實評估TRUE ~ as.character(x)這是最後一個),並且該35 %% 7顯然是0.

我錯過了什麼?

+4

這些語句按順序進行評估,任何與第一個語句相匹配的語句都會得到第一個結果,並且不會被後面的結果覆蓋。 – Marius

+0

我仍然感到困惑,因爲爲什麼最後一條語句TRUE〜as.character(x)被評估。 – tictocchoc

+2

有'x'值不能被35,5或7整除 - 所以在處理前3個語句後仍有值需要處理。如果您仍然感到困惑,您可以嘗試更詳細地解釋爲什麼您認爲應該發生其他事情? – Marius

回答

1

case_when()計算所有語句逐個不管前一個是真的還是假的(因爲它評估TRUE〜as.character(X),這是最後一個)

這是誤導性的,case_when()的輸出是基於第一種說法是正確的。

TRUE ~ as.character(x)意味着如果x不能被5或7整除,那麼x將返回一個字符串,即對於x = 5,將返回「5」。

如果x可被5或7整除,則casewhen()不會評估後續情況。 「嘶嘶聲」和「嗡嗡聲」分別是而不是傳遞給as.character(x)並且它們不一定是因爲它們已經是字符串。

+0

您說得對,'case_when'從第一個真實案例中獲取了值,但實際上後續案例仍在評估中,可以看出它們是否有副作用。例如,這會返回''foo'',但你仍然會從第二種情況得到警告:'case_when(TRUE〜「foo」,TRUE〜warning(「bar」))' –

+0

同樣,這將返回'2' ,但後來'x'是'3',因爲它增加了兩次:'x < - 1; case_when(TRUE〜(x < - x + 1),TRUE〜(x < - x + 1))'。 (很明顯,我不推薦在實際代碼中使用這樣的副作用 - 這僅僅是一個例子。) –

+0

@TimGoodman感謝這是一個好點,我應該知道。我常常被設置爲TRUE〜NA,而不是相應的NA_ [class] _,即使在我認爲TRUE〜從未被評估過的情況下我收到一個錯誤,我也沒有加入這些點。 – bmrn