Tracks
/
R
R
/
Lehrplan
/
Listen
Li

Listen in R

1 Übung

Über Listen

Eine list in R ist eine geordnete Sammlung von Elementen, die sich in einigen Punkten von vectors unterscheidet:

  • Die Elemente können unterschiedliche Typen haben (z. B. numeric mit character gemischt).
  • Die Elemente können komplexe Strukturen sein (z. B. Vektoren, andere Listen usw.).
  • Für den Zugriff auf Elemente gibt es eine etwas andere Syntax.

Vergleiche mit anderen Sprachen sind ungenau. Eine R-list ähnelt ein wenig einem Python-Dictionary, aber die list ist geordnet und lässt sich über einen numerischen Index ansprechen. Sie ähnelt auch ein wenig einem C-struct, nur dass sich die list zur Laufzeit leicht erweitern lässt.

Listen erstellen

Elementen Namen (oft „Tags“ genannt) zu geben, ist bei Listen üblicher als bei Vektoren:

list(x = 5.3, y = 4.2, color = "blue")
#> $x
#> [1] 5.3

#> $y
#> [1] 4.2

#> $color
#> [1] "blue"

Tags sind aber optional, und R verwendet dann einfach Indexnummern:

list(5.3, 4.2, "blue")
#> [[1]]
#> [1] 5.3

#> [[2]]
#> [1] 4.2

#> [[3]]
#> [1] "blue"

Auf Listenelemente zugreifen

Dafür gibt es drei Möglichkeiten, die jeweils in unterschiedlichen Situationen nützlich sind.

1. Mit der $tag-Notation

Sehr verbreitet, wenn die Tag-Namen im Voraus bekannt sind.

point <- list(x = 5.3, y = 4.2, color = "blue")
#> point$x
#> [1] 5.3
#> point$color
#> [1] "blue"

2. Mit der [[tag]]-Notation

Das hat den Vorteil, dass der Tag-Name zur Laufzeit gewählt werden kann. Beachte die doppelten Klammern.

want <- "y"
point[[want]] # same as point$y
#> [1] 4.2

3. Mit dem Positionsindex

Das funktioniert unabhängig davon, ob die Liste Tags hat. Auch hier werden die Klammern verdoppelt.

point[[3]] # same as point$color
#> [1] "blue"

Elemente hinzufügen und löschen

Ganz einfach: Eine Zuweisung an ein Element ändert es, wenn es existiert, und fügt es ein, wenn es neu ist.

point$color <- "red"
point$trust <- TRUE

# str() gives more compact output than the default display
str(point) 
#> List of 4
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"
#>  $ trust: logi TRUE

Zum Löschen weist du dem unerwünschten Element NULL zu.

point$trust <- NULL
str(point)  
#> List of 3
#>  $ x    : num 5.3
#>  $ y    : num 4.2
#>  $ color: chr "red"

Listen sind „rekursive Vektoren“

Die Klasse vector heißt technisch atomic vector, weil sie nur atomare Werte aufnehmen kann: numeric, character, boolean usw. Weil eine list andere Listen enthalten kann, wird sie auch als recursive vector bezeichnet.

Das ist nicht nur ein Punkt der Namensgebung, sondern auch eine Erinnerung daran, dass Listen beliebig komplexe Strukturen haben können. Es liegt in deiner Verantwortung als Programmierer, zu verstehen, was beim Zugriff auf ein Listenelement geliefert wird.

Mehr zur Listenindizierung

Einige Beispiele oben haben doppelte Klammern [[ ]] verwendet, um auf Listenelemente zuzugreifen. Dabei wird versucht, das Element auf seinen zugrunde liegenden Typ zu reduzieren, was nützlich ist, wenn du nur eine Zahl oder einen String möchtest.

Einfache Klammern [ ] machen diese Reduktion nicht, und der zurückgegebene Wert ist eine Teilliste.

point[["color"]]
#> [1] "red"  # flattened

point["color"]
#> $color
#> [1] "red"  # sublist

Auch wenn die Teilliste nicht das ist, was eine unerfahrene R-Programmiererin oder ein unerfahrener R-Programmierer vermutlich möchte, solltest du dir dessen bewusst sein. Aus Gründen der Flexibilität geben viele Standardfunktionen von R eine list zurück, selbst wenn sie wie hier nur einen einzigen atomaren Wert enthält.

Um in einen Vektor umzuwandeln, gibt es zwei Möglichkeiten.

  1. Nimm das erste Element mit [[1]]
  2. Verwende die Funktion unlist().
pt <-point["color"]

pt[[1]]
#> [1] "red" # simple 1-element vector

unlist(pt)
#> color 
#> "red"  # 1-element vector with name

Sei vorsichtig mit unlist(). In diesem einfachen Fall ist es nützlich, die Struktur zu reduzieren, bei komplizierteren Listenelementen kann es aber Überraschungen geben.

Advanced

Interne Darstellung

Eine list wird, wie ein atomarer vector, zusammenhängend gespeichert. Der Unterschied ist, dass numerische und boolesche Vektoren Werte speichern, die Liste aber Referenzen auf Objekte, die an anderer Stelle im Speicher liegen.

Das zu wissen ist für R-Nutzende selten wichtig, aber in einer mehrsprachigen Community wie Exercism kann es für Programmierer hilfreich sein, die mit anderen Sprachen vertraut sind.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab

Lerne Listen