Ersetzen Sie die Schleife mit einer der Funktionen der "apply" -Familie

8

Ich habe data.frames in Listen und normalerweise, wenn ich Daten zentrieren möchte, verwende ich eine Schleife (wie im Beispiel unten zu sehen). Ich möchte eine Funktion der "apply" -Familie verwenden, aber ich kann nicht herausfinden, wie man den Code schreibt.

Ein Beispiel meiner Daten:

%Vor%

Die Werte, die ich verwenden werde, um sie zu zentrieren:

%Vor%

Die Art von Schleife, die ich häufig verwende:

%Vor%

Gibt es eine Möglichkeit, eine Funktion der "apply" -Familie zu verwenden, um dasselbe zu tun, was ich in der obigen Schleife getan habe?

    
Nicso 14.01.2018, 12:35
quelle

6 Antworten

8

Es gibt zwei Dinge, die Sie hier vereinfachen können: Schleifen Sie die Listenelemente und subtrahieren Sie jeden Wert in d separat.

Um die for-Schleife zu ersetzen, können Sie lapply ("l", während wir über die Liste iterieren) verwenden.

%Vor%

Um die Subtraktion zu vereinfachen, können Sie:

  1. Transponieren des Datenrahmens t(i)
  2. Subtraktion durchführen t(i) - d
  3. Transponiere es zurück t(t(i) - d)

Der endgültige Code wäre also:

%Vor%     
PoGibas 14.01.2018, 12:45
quelle
3

1) Sweep Verwenden Sie sweep , um eine Liste von Datenrahmen zu erstellen:

%Vor%

geben:

%Vor%

Siehe auch Wie jede Zeile einer Matrix durch Elemente eines Vektors in R geteilt wird für zahlreiche Ausdrücke, die äquivalent oder fast äquivalent zu sweep sind.

2) skaliere oder verwende scale so; es gibt jedoch eine Liste numerischer Matrizen statt einer Liste von Datenrahmen:

%Vor%

geben:

%Vor%     
G. Grothendieck 14.01.2018 14:43
quelle
1

Hier ist eine Hack'ey-Lösung mit lapply

%Vor%     
snoram 14.01.2018 13:02
quelle
0

Meine Version von Antwort von PoGibas (+1):

%Vor%

Es macht genau dasselbe:

  • Transponiere die data.frame -Objekte
  • Subtrahieren Sie d mithilfe von Recyclingregeln
  • Transponiere sie zurück an die ursprüngliche Position
  • Es gibt matrix -Objekte zurück, was OP nicht wollte.

Ich dachte, da es die Vektorisierung gründlicher verwendet, würde es ein bisschen schneller enden. Es ist jedoch nicht der Fall.

%Vor%     
catastrophic-failure 14.01.2018 17:38
quelle
0

Vielen Dank für die schnellen und interessanten Antworten.

Ich habe alle Lösungen, die Sie gepostet haben, innerhalb der microbenchmark :: microbenchmark-Funktion ausgeführt.

Für die Lösungen, die eine Liste von Matrizen erzeugen, fügte ich (unter Verwendung nur meines derzeitigen Wissens von R) eine zusätzliche Zeile hinzu, um sie in Listen von Datenrahmen umzuwandeln.

%Vor%

Wie Sie sehen werden, erzeugen alle Linien identische Objekte.

Nach fünfmaliger Ausführung der "microbenchmark" -Funktion ist die Lösung ## 7 im obigen Code die schnellere, obwohl die Lösung ## 3 nur ein wenig langsamer ist.

Ich werde jede der von Ihnen vorgeschlagenen Lösungen im Detail studieren und nochmals vielen Dank!

Als Zeichen der Wertschätzung, genießt dieses Lied, das ich wirklich mag! Ссылка

Grüße!

    
Nicso 15.01.2018 09:59
quelle
0

Sie können auch die Funktionen map verwenden, um dasselbe zu erreichen. Insbesondere können Sie map() verwenden, um die Liste env und dann map2() zu durchlaufen, um (gleichzeitig) über d und die einzelnen Datenrahmen env[[1]] und env[[2]] zu loopen. j-k ist der Ort, an dem die Daten zentriert werden.

%Vor%

Nachgeben,

%Vor%     
Japie 21.01.2018 09:00
quelle

Tags und Links