2017-03-01 6 views
3

Meine Datentabelle df hat eine subject Spalte (z. B. "SubjectA", "SubjectB", ...). Jedes Thema beantwortet viele Fragen und die Tabelle ist in einem langen Format, so dass es viele Zeilen für jedes Thema gibt. Die Betreff-Spalte ist ein Faktor. Ich möchte eine neue Spalte erstellen - nennen Sie es subject.id - das ist einfach eine numerische Version von subject. Also für alle Zeilen mit "SubjectA" wäre es 1; für alle Zeilen mit "SubjectB" wäre es 2; usw.Einfach mutieren mit dplyr gibt "falsche Ergebnisgröße" Fehler

Ich weiß, dass eine einfache Möglichkeit, dies mit dplyr zu tun wäre, df %>% mutate(subject.id = as.numeric(subject)) zu rufen. Aber ich habe versucht, es auf diese Weise zu tun:

subj.list <- unique(as.character(df$subject)) 
df %>% mutate(subject.id = which(as.character(subject) == subj.list)) 

Und ich bekomme diese Fehlermeldung:

Error: wrong result size (12), expected 72 or 1 

Warum geschieht das? Ich bin nicht an anderen Möglichkeiten interessiert, dieses spezielle Problem zu lösen. Ich bin eher besorgt, dass meine Unfähigkeit, diesen Fehler zu verstehen, ein tiefes Missverständnis von dplyr oder mutate widerspiegelt. Mein Verständnis ist, dass dieser Anruf sollte konzeptionell gleichwertig sein:

df$subject.id <- NULL 
for (i in 1:nrow(df)) { 
    df$subject.id[i] <- which(as.character(df$subject[i]) == subj.list)) 
} 

Aber das letztere funktioniert und das ehemalige nicht. Warum?

Reproduzierbare Beispiel:

df <- InsectSprays %>% rename(subject = spray) 
subj.list <- unique(as.character(df$subject)) 

# this works 
df$subject.id <- NULL 
for (i in 1:nrow(df)) { 
    df$subject.id[i] <- which(as.character(df$subject[i]) == subj.list) 
} 

# but this doesn't 
df %>% mutate(subject.id = which(as.character(subject) == subj.list)) 

Antwort

1

Die Problem ist, dass Operatoren und Funktionen appli sind durch Mutate vektorisiert. Somit wird which auf den von as.character(df$subject) == subj.list erzeugten Vektor angewendet, nicht auf jede Zeile (wie in Ihrer Schleife).

Mit rowwise wie hier beschrieben würde das Problem lösen: https://stackoverflow.com/a/24728107/3772587

So wird diese Arbeit:

df %>% 
    rowwise() %>% 
    mutate(subject.id = which(as.character(subject) == subj.list)) 
0

Da Ihr df$subject ist ein Faktor, können Sie einfach tun:

df %>% mutate(subj.id=as.numeric(subject)) 

Oder verwenden Sie einen LEFT JOIN Ansatz:

subj.df <- df$subject %>% 
    unique() %>% 
    as_tibble() %>% 
    rownames_to_column(var = 'subj.id') 

df %>% left_join(subj.df,by = c("subject"="value")) 
+0

Vielen Dank für die Antwort. Ich weiß, dass es andere Möglichkeiten gibt, das spezielle Problem zu lösen, aber meine Frage ist, warum das, was ich vorgeschlagen habe, nicht funktioniert. Ich bin besorgt, dass ich ein tiefes Missverständnis von 'muate' oder' dplyr' habe. –

+0

@AdamMorris ah, hmm. Ich kann das nicht ohne weiteres beantworten! Hoffe, jemand kann helfen! – Rahul

Verwandte Themen