2017-07-03 203 views
10

我想使用dplyr::case_whendplyr::mutate創建一個新的變量,我設置一些值丟失,同時重新編碼其它值。與dplyr避免類型衝突:: case_when

但是,如果我嘗試值設置爲NA,我得到一個錯誤,說我們不能創建變量new因爲NA s爲邏輯:

Error in mutate_impl(.data, dots) :
Evaluation error: must be type double, not logical.

有沒有一種辦法值設置爲NA數據幀中使用此非邏輯向量?

library(dplyr)  

# Create data 
df <- data.frame(old = 1:3) 

# Create new variable 
df <- df %>% dplyr::mutate(new = dplyr::case_when(old == 1 ~ 5, 
                old == 2 ~ NA, 
                TRUE ~ old)) 

# Desired output 
c(5, NA, 3) 

回答

10

正如?case_when說:

All RHSs must evaluate to the same type of vector.

你實際上有兩種可能性:

1)創建new作爲數字矢量

df <- df %>% mutate(new = case_when(old == 1 ~ 5, 
            old == 2 ~ NA_real_, 
            TRUE ~ as.numeric(old))) 

注意NA_real_是該數字版本的NA,而且你必須轉換到old數字,因爲你創造了它在你的原始數據幀的整數。

你得到:

str(df) 
# 'data.frame': 3 obs. of 2 variables: 
# $ old: int 1 2 3 
# $ new: num 5 NA 3 

2)作爲一個整數向量

df <- df %>% mutate(new = case_when(old == 1 ~ 5L, 
            old == 2 ~ NA_integer_, 
            TRUE ~ old)) 

這裏,5L部隊5到整數類型創建new,並NA_integerNA整數版本。

所以這次new是整數

str(df) 
# 'data.frame': 3 obs. of 2 variables: 
# $ old: int 1 2 3 
# $ new: int 5 NA 3 
+2

你也可以做'as.numeric(NA)'或'as.integer(NA)'的'NA'情況下,如'NA_real_'和'NA_integer_'有點令人討厭,並且很少在這樣的事情之外使用。 – Marius

+0

不錯。此外,要顯示:相同(NA_real_,as.numeric(NA))會生成TRUE。 – user3614648

+0

@hadley這個答案現在已經很清楚,我,但我花了一段時間才搞清楚。在tidyverse'case_when'文檔中有一個這樣的例子會很有幫助。在我的情況丟失了所有值分組的數據時,平均(X [1:2],na.rm = T)中產生的NaN結果。將這些情況重新編碼爲NA_real_,以修正它。 –

2

試試這個嗎?

df %>% dplyr::mutate(new = dplyr::case_when(.$old == 1 ~ 5, 
                .$old == 2 ~ NA_real_, 
                TRUE~.$old)) 

> df 
    old new 
1 1 5 
2 2 NA 
3 3 3