347 Stimmen

Wie verwendet man Listen in R richtig?

Kurzer Hintergrund: Viele (die meisten?) modernen Programmiersprachen, die weit verbreitet sind, haben zumindest eine Handvoll ADTs [abstrakte Datentypen] gemeinsam, vor allem,

  • String (eine Folge von Zeichen)

  • Liste (eine geordnete Sammlung von Werten), und

  • kartenbasierter Typ (ein ungeordnetes Array, das Schlüssel auf Werte abbildet)

In der Programmiersprache R sind die ersten beiden als character y vector .

Als ich begann, R zu lernen, waren zwei Dinge fast von Anfang an klar: list ist der wichtigste Datentyp in R (denn er ist die übergeordnete Klasse für die R data.frame ), und zweitens konnte ich einfach nicht verstehen, wie sie funktionieren, zumindest nicht gut genug, um sie in meinem Code korrekt zu verwenden.

Zum einen schien es mir, dass R's list Datentyp war eine unkomplizierte Implementierung des map ADT ( dictionary in Python, NSMutableDictionary in Objective C, hash in Perl und Ruby, object literal in Javascript, und so weiter).

Sie erstellen sie zum Beispiel genauso wie ein Python-Wörterbuch, indem Sie Schlüssel-Wert-Paare an einen Konstruktor übergeben (in Python ist das dict no list ):

x = list("ev1"=10, "ev2"=15, "rv"="Group 1")

Und Sie greifen auf die Elemente einer R-Liste genauso zu wie auf die eines Python-Wörterbuchs, z. B., x['ev1'] . Ebenso können Sie auch nur die 'Tasten' oder nur die Werte von:

names(x)    # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"

unlist(x)   # fetch just the 'values' of an R list
#   ev1       ev2        rv 
#  "10"      "15" "Group 1" 

x = list("a"=6, "b"=9, "c"=3)  

sum(unlist(x))
# [1] 18

aber R list s sind auch im Gegensatz zu andere map-type ADTs (von den Sprachen, die ich sowieso gelernt habe). Ich vermute, dass dies eine Folge der ursprünglichen Spezifikation für S ist, d.h. der Absicht, eine Daten-/Statistik-DSL [domänenspezifische Sprache] von Grund auf zu entwickeln.

drei signifikante Unterschiede zwischen R list s und Mapping-Typen in anderen weit verbreiteten Sprachen (z. B. Python, Perl, JavaScript):

erste , list s in R sind ein bestellt Auflistung, genau wie Vektoren, auch wenn die Werte verschlüsselt sind (d.h. die Schlüssel können beliebige Hash-Werte sein, nicht nur sequentielle Ganzzahlen). Fast immer ist der Mapping-Datentyp in anderen Sprachen ungeordnet .

zweite , list s können von Funktionen zurückgegeben werden, auch wenn Sie nie eine list wenn Sie die Funktion aufrufen, und auch wenn die Funktion, die die list enthält keine (explizite) list Konstruktor (Natürlich können Sie dies in der Praxis umgehen, indem Sie das zurückgegebene Ergebnis in einen Aufruf von unlist ):

x = strsplit(LETTERS[1:10], "")     # passing in an object of type 'character'

class(x)                            # returns 'list', not a vector of length 2
# [1] list

A dritte Besonderheit von R's list s: es scheint nicht so, dass sie Mitglieder eines anderen ADT sein können, und wenn man das versucht, wird der primäre Container zu einem list . Z.B.,

x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)

class(x)
# [1] list

Es ist nicht meine Absicht, die Sprache oder die Art und Weise, wie sie dokumentiert ist, zu kritisieren; auch will ich nicht behaupten, dass etwas an der list Datenstruktur oder wie sie sich verhält. Alles, was ich will, ist mein Verständnis für ihre Funktionsweise zu korrigieren, damit ich sie in meinem Code korrekt verwenden kann.

Das sind die Dinge, die ich gerne besser verstehen würde:

  • Welche Regeln bestimmen, wann ein Funktionsaufruf eine list (z.B., strsplit oben zitierten Ausdruck)?

  • Wenn ich nicht explizit Namen für eine list (z.B., list(10,20,30,40) ) sind die Standardnamen einfach fortlaufende Ganzzahlen, die mit 1 beginnen? (Ich nehme an, bin mir aber keineswegs sicher, dass die Antwort ja lautet, sonst könnten wir diese Art von list zu einem Vektor mit einem Aufruf von unlist .)

  • Warum machen diese zwei verschiedene Betreiber, [] und [[]] zurück, die dieselbe Ergebnis?

    x = list(1, 2, 3, 4)

    beide Ausdrücke ergeben "1":

    x[1]

    x[[1]]

  • warum sind diese beiden Ausdrücke no das gleiche Ergebnis liefern?

    x = list(1, 2, 3, 4)

    x2 = list(1:4)

Bitte verweisen Sie mich nicht auf die R-Dokumentation ( ?list , R-intro ) Ich habe ihn sorgfältig gelesen, aber er hilft mir nicht bei der Beantwortung der Fragen, die ich gerade oben zitiert habe.

(Schließlich habe ich vor kurzem von einem R-Paket (verfügbar auf CRAN) namens hash die Folgendes implementiert konventionell Map-artiges Verhalten über eine S4-Klasse; ich kann dieses Paket durchaus empfehlen).

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