Definieren Sie den Wert einer Spalte in einem Datenrahmen basierend auf 2 Schlüsseln aus einem anderen Datenrahmen

7

Ich habe folgenden Datenrahmen:

%Vor%

und ich möchte eine neue Spalte "Wert" basierend auf den Spalten a und b und der Umwandlungstabelle unten erstellen:

%Vor%

Ich habe versucht, es mit dplyr :: muate ohne viel Erfolg zu tun ...

%Vor%

längere Objektlänge ist kein Vielfaches kürzerer Objektlänge

Meine Erwartung wäre, einen Datenrahmen wie oben 'df' mit dem zusätzlichen Spaltenwert wie folgt zu erhalten:

%Vor%     
ines vidal 17.01.2017, 11:49
quelle

6 Antworten

7

Eine weitere Option, diesmal mit Matrizen.

%Vor%

outer vergleicht jedes Element des Vektors von df mit demjenigen von conv und erzeugt für jeden Aufruf eine Boolesche Matrix. Da TRUE 1 ist, wenn Sie alle vier Matrizen hinzufügen, ist der gewünschte Index die Spalte mit dem meisten TRUE s, die Sie mit max.col erhalten können. Untermenge output , und Sie haben Ihr Ergebnis.

Der Vorteil der Arbeit mit Matrizen ist, dass sie schnell sind. Verwenden von @ Phanns Benchmarks in 1.000 Zeilen:

%Vor%

und auf 100.000 Zeilen:

%Vor%     
alistaire 18.01.2017, 03:19
quelle
9

Eine mögliche relativ einfache und sehr effiziente data.table-Lösung mit binären Nicht-Equi-Joins

%Vor%

Wenn die output -Spalte nur der Zeilenindex innerhalb von conv ist, können Sie diese Verknüpfung noch effizienter gestalten, indem Sie nach den Zeilenindizes fragen, indem Sie which = TRUE

angeben %Vor%     
David Arenburg 17.01.2017 12:32
quelle
6

Wir können es mit Map mit na.locf

versuchen %Vor%

Oder eine andere Möglichkeit, die Map -Lösung zu schreiben, besteht darin, die Spalten 'a' und 'b' als Argumente zu übergeben und dann die logische Auswertung mit Spalten von 'conv' auszuführen, um den Wert 'output' und% co_de zu extrahieren % die unlist Ausgabe

%Vor%

HINWEIS: Die zweite Lösung sollte langsamer sein, da wir die Zeilen des Datasets durchlaufen, während die erste Lösung die Zeilen "conv" durchläuft (von denen wir annehmen, dass sie nicht viele Zeilen umfassen sollten)

    
akrun 17.01.2017 11:58
quelle
5

Ein anderer Ansatz, der apply verwendet:

%Vor%

BEARBEITEN:

Da es bisher mehrere Antworten gibt, habe ich die Zeit überprüft, die für die Verarbeitung der Daten benötigt wird. Ich habe ein etwas größeres Beispiel (ähnlich dem mit Zufallszahlen) erstellt:

%Vor%

Mit 1000 Zufallszahlen:

%Vor%

Mit 10000 Zufallszahlen (gleicher Startwert) bekomme ich:

%Vor%     
Phann 17.01.2017 12:09
quelle
4

Hier ist ein weiterer Versuch, findInterval s Effizienz sowohl auf Speicher als auch auf Geschwindigkeit zu verwenden. Ein bequemeres Format von conv "data.frame" könnte

sein

(i) eine "Liste" der Intervalle für jede Variable, die sich nicht überschneiden:

%Vor%

und (ii) eine Lookup-Struktur, die die Gruppe jedes gepaarten Intervalls zwischen den beiden Variablen enthält:

%Vor%

wo wir zum Beispiel bemerken, dass das erste Intervall von "a" & amp; & amp; Sekunde von "b" wird eine "3" usw. zugewiesen.

Dann können wir verwenden:

%Vor%

Und die Benchmarks von Phann und Alistaire erweitern (umgeschrieben, teilweise aus Gründen der Zweckmäßigkeit):

%Vor%     
alexis_laz 20.01.2017 19:19
quelle
3

Wir können mapply für zwei Variablen a und b verwenden und die richtige output Variable basierend auf dem Bereich

finden %Vor%     
Ronak Shah 17.01.2017 12:22
quelle

Tags und Links