2017-07-03 6 views
10

Ich versuche dplyr::case_when innerhalb dplyr::mutate zu verwenden, um eine neue Variable zu erstellen, wo ich einige Werte auf fehlende und andere Werte gleichzeitig recode.Typkonflikte vermeiden mit dplyr :: case_when

Allerdings, wenn ich versuche, Werte zu NA zu setzen, bekomme ich eine Fehlermeldung, dass wir die Variable new weil NA s logisch nicht schaffen können:

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

Gibt es einen Weg, um Werte zu NA setzen in ein nicht logischer Vektor in einem Datenrahmen mit diesem?

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) 

Antwort

10

Wie gesagt in ?case_when:

All RHSs must evaluate to the same type of vector.

Sie haben tatsächlich zwei Möglichkeiten:

1) Erstellen Sie new als numerischer Vektor

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

Beachten Sie, dass NA_real_ ist das numerische Version von NA, und dass Sie old in numerisch konvertieren müssen, da Sie es als eine Ganzzahl in Ihrem ursprünglichen Dataframe erstellt haben.

Sie erhalten:

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

2) Erstellen new als Integer-Vektor

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

Hier 5L Kräfte 5 in den Integer-Typ, und NA_integer die ganzzahlige Version von NA.

Dieses Mal new ist integer:

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

Sie können auch tun 'as.numeric (NA)' oder 'as.integer (NA)' für die 'NA' Fällen als' NA_real_' und 'NA_integer_' sind ein bisschen nervig, um sich daran zu erinnern und selten außerhalb solcher Dinge zu benutzen. – Marius

+0

Schön. Auch zu zeigen: identisch (NA_real_, as.numeric (NA)) erzeugt TRUE. – user3614648

+0

@hadley Diese Antwort ist mir jetzt klar, aber es dauerte eine Weile, bis ich es herausgefunden hatte. Es wäre sehr hilfreich, ein Beispiel dafür in der ordentlichen "case_when" -Dokumentation zu haben. In meinem Fall, wenn alle Werte für gruppierte Daten fehlten, erzeugte Mittelwert (x [1: 2], na.rm = T) ein NaN-Ergebnis. diese Fälle in NA_real_ umzukodieren, wurde behoben. –

2

Versuchen Sie das?

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