2015-05-19 10 views
6

Meine Frage hat starke Ähnlichkeiten mit this one und this other one, aber mein Datensatz ist ein bisschen anders und ich kann nicht scheinen, dass diese Lösungen funktionieren . Bitte entschuldigen Sie, wenn ich etwas missverstanden habe und diese Frage überflüssig ist.R - Konvertieren Sie verschiedene Dummy/logische Variablen in eine einzige kategoriale Variable/Faktor aus ihrem Namen

Ich habe einen Datensatz wie diese:

df <- data.frame(
    id = c(1:5), 
    conditionA = c(1, NA, NA, NA, 1), 
    conditionB = c(NA, 1, NA, NA, NA), 
    conditionC = c(NA, NA, 1, NA, NA), 
    conditionD = c(NA, NA, NA, 1, NA) 
) 
# id conditionA conditionB conditionC conditionD 
# 1 1   1   NA   NA   NA 
# 2 2   NA   1   NA   NA 
# 3 3   NA   NA   1   NA 
# 4 4   NA   NA   NA   1 
# 5 5   1   NA   NA   NA 

(Beachten Sie, dass abgesehen von diesen Spalten, ich habe eine Menge von anderen Spalten, die nicht von der aktuellen Manipulation betroffen sein sollten.)

so

, ich beobachte, dass conditionA, conditionB, conditionC und conditionD sind für beide Seiten exclusives und besser werden sollte, als eine einzelne kategoriale Variable dargestellt, dh factor, dass sollte wie folgt aussehen:

# id  type 
# 1 1 conditionA 
# 2 2 conditionB 
# 3 3 conditionC 
# 4 4 conditionD 
# 5 5 conditionA 

Ich habe mit gather oder unite von tidyr untersucht, aber es entspricht nicht diesen Fall (mit unite wir die Informationen aus dem Variablennamen verlieren).

Ich versuchte mit kimisc::coalescence.na, wie in der ersten Antwort vorgeschlagen, aber 1. Ich brauche zuerst einen Faktor Wert basierend auf dem Namen für jede Spalte, 2. Es funktioniert nicht wie erwartet, nur einschließlich der ersten Säule:

library(kimisc) 
# first, factor each condition with a specific label 
df$conditionA <- df$conditionA %>% 
    factor(levels = 1, labels = "conditionA") 
df$conditionB <- df$conditionB %>% 
    factor(levels = 1, labels = "conditionB") 
df$conditionC <- df$conditionC %>% 
    factor(levels = 1, labels = "conditionC") 
df$conditionD <- df$conditionD %>% 
    factor(levels = 1, labels = "conditionD") 

# now coalesce.na to merge into a single variable 
df$type <- coalesce.na(df$conditionA, df$conditionB, df$conditionC, df$conditionD) 

df 
# id conditionA conditionB conditionC conditionD  type 
# 1 1 conditionA  <NA>  <NA>  <NA> conditionA 
# 2 2  <NA> conditionB  <NA>  <NA>  <NA> 
# 3 3  <NA>  <NA> conditionC  <NA>  <NA> 
# 4 4  <NA>  <NA>  <NA> conditionD  <NA> 
# 5 5 conditionA  <NA>  <NA>  <NA> conditionA 

habe ich versucht, die anderen Vorschläge aus der zweiten Frage, haben aber keinen gefunden, der mir das erwartete Ergebnis bringen würde ...

+0

einen Dummy als 'NA' /' Encoding 1 'statt '0' /' 1' hat keine Oberseite, die ich kenne. Ich habe das in letzter Zeit sehr oft auf SO gesehen. – Frank

+1

@Frank: Eigentlich wurde es nicht als Dummy-Variable gedacht (zB für Regression): Ich habe alle diese Daten in Excel manuell eingegeben und jedes Mal eine '1' gesetzt, wenn eine Bedingung erfüllt war (und nicht den Rest gefüllt hat) mit '0'). Ich bin nicht sicher, ob ich das eine Dummy-Variable nennen sollte (aber das ist der Begriff, dem ich begegnet bin) ... –

Antwort

4

Sie auch versuchen können:

colnames(df)[2:5][max.col(!is.na(df[,2:5]))] 
#[1] "conditionA" "conditionB" "conditionC" "conditionD" "conditionA" 

Das obige funktioniert, wenn eine und nur eine Spalte für jede Zeile einen anderen Wert als NA hat. Wenn die Werte einer Zeile können alle NA s sein, dann können Sie versuchen:

mat<-!is.na(df[,2:5]) 
colnames(df)[2:5][max.col(mat)*(NA^!rowSums(mat))] 
+1

Ziemlich sicher, dass dies der effizienteste ist. 4x so schnell wie Stephen auf 'big_df <- rbind (df, df); für (i in 1:18) big_df <- rbind (big_df, big_df) ' – Frank

+1

Es funktioniert ganz gut, außer dass, wenn eine Zeile' 'in allen vier Bedingungen hat, dann gibt dieser Code eine der vier Bedingungen (nicht immer das gleiche, ich verstehe nicht mal warum), wenn es den resultierenden Wert lieber auf ' 'belassen soll. Gibt es eine Möglichkeit, das zu vermeiden? –

+1

@Sergebibauw Ich habe eine Bearbeitung vorgenommen, um diese Fälle zu bearbeiten. – nicola

1
library(tidyr) 
library(dplyr) 

df <- df %>% 
    gather(type, count, -id) 
df <- df[complete.cases(df),][,-3] 
df[order(df$id),] 
    id  type 
1 1 conditionA 
7 2 conditionB 
13 3 conditionC 
19 4 conditionD 
5 5 conditionA 
+1

Ein 'dplyr'-esque Ansatz wäre' df%>% sammeln (Typ, Wert, -id)%>% na.omit()%>% auswählen (-Wert)%>% ordnen (id) ' –

+0

Ich mag, danke! –

6

Versuchen:

# id  type 
#1 1 conditionA 
#2 2 conditionB 
#3 3 conditionC 
#4 4 conditionD 
#5 5 conditionA 

aktualisieren

:

library(dplyr) 
library(tidyr) 

df %>% gather(type, value, -id) %>% na.omit() %>% select(-value) %>% arrange(id) 

Welche gibt

Um den Fall, dass Sie ausführliche in den Kommentaren zu umgehen, können Sie den Vorgang auf den gewünschten Teil des Datenrahmens tun und dann left_join() die anderen Spalten:

df %>% 
    select(starts_with("condition"), id) %>% 
    gather(type, value, -id) %>% 
    na.omit() %>% 
    select(-value) %>% 
    left_join(., df %>% select(-starts_with("condition"))) %>% 
    arrange(id) 
+0

Großartig! Ich hatte nicht darüber nachgedacht, 'gather' mit' na.omit' zu kombinieren, um dieses Ergebnis zu erhalten! Jetzt habe ich noch ein großes Problem: der eigentliche Datensatz hat eine Menge mehr Spalten, und viele von ihnen sind teilweise leer. 'na.omit' würde dann diese Beobachtungen löschen, obwohl sie eine Bedingung haben ... (Auch in' gather (type, value, -id) ', wenn ich ausschließen muss (' -x') etwas wie 70 Spalten, gibt es einen schnellen Weg, um es zu tun?) –

+1

@SergeBibauw Würde so etwas für Sie arbeiten: 'df%>% wählen (starts_with (" Bedingung "), id)%>% sammeln (Typ, Wert , -id)%>% na.omit()%>% select (-wert)%>% left_join (., df%>% select (-start_with ("bedingung")))%>% ordnen (id) ' ? –

+0

Danke! Ich dachte mir, dass ich nur die gewünschten Spalten auswählen, den Prozess "Sammeln" usw. anwenden und dann das Ergebnis in den ursprünglichen Datenrahmen "reinjizieren" sollte. –

Verwandte Themen