Erstellen von variablen Indikatorspalten in der dplyr-Kette

8

Aktualisiert : Entschuldigung für die Antworten, in meinem ursprünglichen Beispiel habe ich übersehen, dass data.frame() var als Faktor und nicht als Zeichenvektor erstellt hat, wie ich es beabsichtigt hatte. Ich habe das Beispiel korrigiert und dadurch wird mindestens eine der Antworten unterbrochen.

- Original -

Ich habe einen Datenrahmen, an dem ich eine Reihe von dplyr und tidyr Manipulationen durchführe, und ich würde gerne Spalten für Indikatorvariablen hinzufügen, die codiert werden als 0 oder 1, und mache das in der dplyr-Kette . Jede Ebene eines Faktors (gegenwärtig als Zeichenvektoren gespeichert) sollte in einer separaten Spalte codiert sein, und die Spaltennamen sind eine Verkettung eines festen Präfixes mit dem Variablenpegel, z. var hat die Ebene a , die neue Spalte var_a ist 1 und alle anderen Zeilen von var_a sind 0.

Das folgende minimale Beispiel, das Basis R verwendet, produziert genau die Ergebnisse, die ich möchte (Danke an diesen Blogbeitrag ), aber ich würde gerne alles in die dplyr -Kette einrollen und kann mir nicht vorstellen, wie es geht.

%Vor%

Beachten Sie, dass der reale Datensatz mehrere Spalten enthält, die beim Erstellen der Indikatorvariablen nicht geändert oder gelöscht werden sollten, mit Ausnahme der Spalte var , die in den Typ Faktor .

    
Tom 11.03.2016, 15:02
quelle

3 Antworten

5

Es ist nicht schön, aber diese Funktion sollte funktionieren

%Vor%

Hier ist ein Beispiel data.frame

%Vor%

und Sie geben die Spalten an, die Sie als Zeichenvektor erweitern möchten. Sie können

tun %Vor%

oder

%Vor%     
MrFlick 11.03.2016, 16:46
quelle
3

Die einzige Voraussetzung dafür, dass eine Funktion Teil einer dplyr-Pipeline ist, ist, dass sie einen Datenrahmen als Eingabe akzeptiert und einen Datenrahmen als Ausgabe zurückgibt. Also nutze model.matrix :

%Vor%     
Hong Ooi 11.03.2016 17:10
quelle
2

Es ist möglich, ohne eine Funktion zu erstellen, obwohl es lapply erfordert. Wenn var ein Faktor ist, können Sie mit seinen Ebenen arbeiten; Wir können seine Spalten an ein lapply binden, das die Ebenen von var umläuft und die Werte erstellt, sie mit setNames benennt und sie in ein tbl_df konvertiert.

%Vor%

gibt

zurück %Vor%

Wenn var ein Zeichenvektor ist, kein Faktor, können Sie dasselbe tun, aber unique anstelle von levels verwenden:

%Vor%

Zwei Anmerkungen:

  • Dieser Ansatz funktioniert unabhängig vom Datentyp, ist aber langsamer. Da Ihre Daten so groß sind, dass es darauf ankommt, ist es wahrscheinlich sinnvoll, die Daten trotzdem als factor zu speichern, da sie viele wiederholte Ebenen enthalten.
  • Beide Versionen ziehen Daten von df$var , da sie in der aufrufenden Umgebung existieren, nicht so wie sie in einer größeren Kette existieren, und nehmen an, dass var in was auch immer es übergeben wird unverändert ist. Um den dynamischen Wert von var neben dplyr 's normal NSE zu referenzieren ist eher ein Schmerz, soweit ich gesehen habe.

Eine weitere Alternative, die etwas einfacher ist und factor -agnostic mit reshape2::dcast :

%Vor%

Er zieht immer noch die Version von df aus der aufrufenden Umgebung, sodass die Kette wirklich nur bestimmt, zu was Sie sich verbinden. Weil es cbind anstelle von bind_cols verwendet, ist das Ergebnis auch ein data.frame , nicht tbl_df . Wenn Sie also alle tbl_df behalten wollen (intelligent, wenn die Daten groß sind), Ich muss die cbind durch bind_cols(as_data_frame( ... )) ersetzen; bind_cols scheint die Konvertierung für Sie nicht ausführen zu wollen.

Beachten Sie jedoch, dass diese Version zwar einfacher ist, aber vergleichsweise langsamer ist, sowohl in factor data:

%Vor%

und Zeichenkette Daten:

%Vor%

Für kleine Daten spielt das keine Rolle, aber für größere Daten lohnt es sich, mit der Komplikation fertig zu werden.

    
alistaire 11.03.2016 17:48
quelle

Tags und Links