445 Stimmen

Warum ist `[` besser als `Teilmenge`?

Wenn ich einen data.frame filtern muss, d.h. Zeilen extrahieren, die bestimmte Bedingungen erfüllen, verwende ich lieber die subset Funktion:

subset(airquality, Month == 8 & Temp > 90)

Anstatt die [ Funktion:

airquality[airquality$Month == 8 & airquality$Temp > 90, ]

Es gibt zwei Hauptgründe für meine Präferenz:

  1. Ich finde, der Code liest sich besser von links nach rechts. Selbst Leute, die nichts über R wissen, können erkennen, was die subset Anweisung oben tut.

  2. Da Spalten als Variablen in der Datei select Ausdruck kann ich einige Tastenanschläge einsparen. In meinem obigen Beispiel musste ich nur Folgendes eingeben airquality einmal mit subset sondern dreimal mit [ .

Ich lebte also glücklich, indem ich subset überall, weil es kürzer ist und sich besser liest, und ich habe sogar meine R-Kollegen von seiner Schönheit überzeugt. Doch gestern brach meine Welt zusammen. Beim Lesen der subset Dokumentation ist mir dieser Abschnitt aufgefallen:

Warnung

Dies ist eine Komfortfunktion, die für den interaktiven Einsatz gedacht ist. Für die Programmierung ist es besser, die Standardfunktionen zur Unterteilung wie [ zu verwenden, und insbesondere die nicht standardmäßige Auswertung des Arguments Untermenge kann unvorhergesehene Folgen haben.

Könnte jemand klären, was die Autoren meinen?

Erstens: Was meinen sie mit " zur interaktiven Nutzung "? Ich weiß, was eine interaktive Sitzung ist, im Gegensatz zu einem Skript, das im BATCH-Modus ausgeführt wird, aber ich verstehe nicht, was das für einen Unterschied machen soll.

Könnten Sie dann bitte erklären " die nicht standardmäßige Bewertung der Argumentteilmenge " und warum es gefährlich ist, vielleicht mit einem Beispiel?

265voto

joran Punkte 163857

Diese Frage wurde in den Kommentaren von @James gut beantwortet, der auf eine ausgezeichnete Erklärung von Hadley Wickham über die Gefahren von subset (und ähnliche Funktionen) [hier] . Lesen Sie es!

Die Lektüre ist etwas lang, daher ist es vielleicht hilfreich, hier das Beispiel aufzuführen, das Hadley verwendet und das die Frage "Was kann schief gehen?" am direktesten anspricht:

Hadley schlägt folgendes Beispiel vor: Nehmen wir an, wir wollen einen Datenrahmen mit Hilfe der folgenden Funktionen untergliedern und dann neu ordnen:

scramble <- function(x) x[sample(nrow(x)), ]

subscramble <- function(x, condition) {
  scramble(subset(x, condition))
}

subscramble(mtcars, cyl == 4)

Dies gibt den Fehler zurück:

Fehler in eval(expr, envir, enclos) : Objekt 'cyl' nicht gefunden

weil R nicht mehr "weiß", wo das Objekt namens "cyl" zu finden ist. Er weist auch auf die wirklich bizarren Dinge hin, die passieren können, wenn es zufällig ein Objekt namens "cyl" in der globalen Umgebung gibt:

cyl <- 4
subscramble(mtcars, cyl == 4)

cyl <- sample(10, 100, rep = T)
subscramble(mtcars, cyl == 4)

(Führen Sie sie aus und überzeugen Sie sich selbst, es ist ziemlich verrückt).

36voto

bartektartanus Punkte 14061

Auch [ ist schneller:

require(microbenchmark)        
microbenchmark(subset(airquality, Month == 8 & Temp > 90),airquality[airquality$Month == 8 & airquality$Temp > 90,])
    Unit: microseconds
                                                           expr     min       lq   median       uq     max neval
                     subset(airquality, Month == 8 & Temp > 90) 301.994 312.1565 317.3600 349.4170 500.903   100
     airquality[airquality$Month == 8 & airquality$Temp > 90, ] 234.807 239.3125 244.2715 271.7885 340.058   100

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X