Lists

Das List-Objekt in R

Heute kommen wir zu einer weiteren Datenstruktur in R, nämlich den Listen. Mit diesem Post wird gleichzeitig die „Getting Started“-Kategorie etwas abrundet, da es jetzt zu allen grundlegenden Datenstrukturen einen Post gibt (Vektoren, Data Frames, Matrizen und Listen). Hat man diese verschiedenen Strukturen verstanden, fällt das Programmieren mit R schon wesentlich einfacher. Du weißt dann, wie du Daten effizienter umstrukturierst und mit wenigen Zeilen zu den gewünschten Ergebnissen gelangen kannst (zumindest ist es mein Ziel, dir das näherzubringen!). Um Listen in R zu verstehen ist es also hilfreich, wenn du die anderen Posts vorher gelesen hast.

Listen allgemein

Was sind also Listen in R? Einfach gesagt sind Listen eine Kollektion von verschiedenen R-Objekten (welche selbst entsprechend unterschiedlich strukturiert sein können). Listen können also nicht nur Vektoren, sondern auch ganze Datensätze oder Funktionen enthalten. Nicht nur das: Listen können sogar selbst wiederum aus verschiedenen Listen bestehen. Auch wenn die Informationen in einer list sehr komplex und mehrdimensional sein können, so ist eine Liste selbst eindimensional; sie hat N Elemente, die durch mylist[[k]] angesprochen werden können. Die Elemente selbst können z.B. wiederum Reihen und Spalten haben, aber das hat genaugenommen nichts mit der Liste selbst zu tun. Schauen wir uns jetzt an, wie Listen erstellt werden und wie man mit ihnen arbeitet.

Erstellen von Listen

Listen werden ganz einfach mit list erstellt. Im Folgenden bauen wir uns eine Liste mit vier Vektoren verschiedener Länge und mit verschiedenen Variablentypen. Die Liste soll Informationen über einen hypothetischen Kurs für die Einführung in Listen enthalten:

lstCourse <- list(Name="Introduction to Lists", 
                  Dates=as.Date(c("2016-09-28", "2017-11-13")),
                  Tags=c("List", "R", "Fundamentals"),
                  Ratings=c(9.7, 9.5, 9.8, 0.5, 9.3, 9.3, 8.9))

Wir sehen: Es wurde eine Liste lstCourse erstellt, welche vier Elemente enthält. Die Elemente tragen die Namen 'Name', 'Dates', 'Tags' und 'Ratings'.

Auswahl von Elementen

Wir können diese Elemente nun ganz einfach durch deren Namen ansprechen: lstCourse$Name. Wir können uns so zum Beispiel anschauen, wie viele Tags für den Kurs existieren: length(lstCourse$Tags). Oder wir berechnen den Mittelwert für das Kurs-Rating (... die 0.5 ist natürlich ein Ausreißer und wird nicht berücksichtigt...): mean(lstCourse$Ratings[-4]). In dieser Zeile sprechen wir das Element 'Ratings' von der Liste an, treffen eine bestimmte Auswahl (wir wählen den Vektor ohne das vierte Element), und lassen uns davon den Mittelwert mit Hilfe von mean ausgeben. Wir können die Elemente einer Liste übrigens auch durch deren Position ansprechen: lstCourse[[2]]. Die doppelten eckigen Klammern sind hier erwünscht; benutzt man nur eine, so liefert R uns nicht den entsprechenden Objekttyp des Objekts an der Stelle, sondern wieder eine Liste. Wir können uns so zum Beispiel eine Subliste durch lstCourse[1:2] ausuwählen. Man sollte übrigens lieber Namen für die Elemente benutzen, da man sie so unabhängig von deren Position in der Liste ansprechen kann - und das verhindert Fehler im Code.

Hinzufügen und Löschen von Elementen

Nun haben wir eine Liste erstellt. Aber was ist, wenn wir Elemente hinzufügen wollen? Auch hier gibt es verschiedene Möglichkeiten. Zum einen können wir ganz einfach mit dem von Data Frames gewohnten Verfahren Elemente namentlich hinzufügen: lstCourse$Creator <- "Thore Johannsen". Zum anderen können wir ein neues Element per Index ansprechen: lstCourse[[6]] <- TRUE. Wir sehen hierbei allerdings, dass dieses Element keinen Namen hat und somit auch nicht darüber angesprochen werden kann. Möchten wir ein Element aus der Liste löschen, so können wir das durch die Zuordnung von NULL tun: lstCourse[[6]] <- NULL.

Nützliche Funktionen

Es kann immer hilfreich sein, sich die Namen der Elemente einer Liste anzuschauen: names(lstCourse). Genauso wird man hin und wieder wissen wollen, wie viele Elemente eine Liste überhaupt enthält: length(lstCourse).

Komplexeres Beispiel

Kommen wir zu einem etwas komplexeren Beispiel. Unsere Liste soll jetzt nicht nur aus Vektoren, sondern auch aus zwei Data Frames bestehen. Mir ist eingefallen, dass man eine Liste für Informationen über eine Band benutzen kann: Wir haben den Bandnamen, einen Datensatz bzgl. Diskographie, und einen Datensatz bzgl. der Bandmitglieder.

Erstellen der Liste

Ich werde hier nicht mehr auf die Details eingehen, sondern den Code für sich sprechen lassen:

#Band name
BandName <- "Dream Theater"

#Discography
AlbumTitle <- c("Train of Thought", "Octavarium", "Systematic Chaos")
AlbumYear <- c(2003, 2005, 2007)
dfDiscography <- data.frame(Title=AlbumTitle, Year=AlbumYear, 
                            stringsAsFactors=FALSE)

#Members
MemberName <- c("John", "John", "James", "Jordan", "Mike")
MemberAge <- c(49, 49, 53, 60, 53)
MemberInstrument <- c("Bass", "Guitar", "Vocals", "Keyboards", "Drums")
dfMembers <- data.frame(Name=MemberName, Age=MemberAge, 
                        Instrument=MemberInstrument,
                        stringsAsFactors=FALSE)

#List
lstBand <- list(Name=BandName, Discography=dfDiscography, Members=dfMembers)

Die Liste besteht nun aus einem Vektor 'Name', der lediglich den Bandnamen enthält, aus einem Data Frame 'Discography', der drei Alben mit entsprechendem Veröffentlichungsjahr enthält, und einem weiteren Data Frame 'Members', der Informationen über die Bandmitglieder (Name, Alter, Instrument) beinhaltet.

Informationen abfragen

Als erstes, ganz simpel, fragen wir den Namen der Band ab: lstBand$Name. Okay, schauen wir uns jetzt an, wie das Album von 2003 heißt: lstBand$Discography$Title[lstBand$Discography$Year==2003]. Hier sehen wir übrigens sehr gut, dass wir durch das $-Zeichen immer wieder die Elemente des jeweiligen Objekts abfragen können. lstBand enthält das Objekt Discography, und da dieses selbst ein data.frame ist, können wir von diesem wiederum das Element Title (bzw. Year) abfragen. Wie üblich für Data Frame können wir auch eine gesamte Zeile abfragen, beispielsweise: lstBand$Members[lstBand$Members$Name=="Jordan", ]. Dieser Code liefert uns die gesamte Zeile für das Bandmitglied 'Jordan'.

Funktionen auf Listen

Schauen wir uns nochmal list-spezifische Funktionen an. Dazu ein weiteres Beispiel: Filmbewertungen.

Liste erstellen

Wir bauen uns eine einfache Liste, welche Bewertungen für drei Filme beinhaltet:

lstRating <- list(Movie1=c(4, 6, 5, 5, 4, 7, 6, 7, 4, 5, 5, 6, 3, 4),
                  Movie2=c(7, 7, 9, 8, 8, 7, 9, 9, 6, 7),
                  Movie3=c(8, 9, 8, 7, 7, 8))

Wir sehen, dass es für die drei Filme unterschiedlich viele Bewertungen gibt. Die gegebenen Informationen würden somit nicht in ein Data Frame passen. Unser Ziel ist es nun, die Mittelwerte der Bewertungen zu berechnen.

Statistiken berechnen

Natürlich können wir jeden Film einzeln ansprechen und entsprechende Statistiken je Film erstellen (Beispiel: max(lstRating$Movie2)). Allerdings ist das aufwändig und vor allem unpraktikabel, sobald wir mehr und mehr Filme dazubekommen. Zum Glück gibt es Funktionen der apply-Familie, welche eine Funktion für jedes Element in einem Objekt ausführen. Voilà: lapply(lstRating, mean). Wunderbar! Mit einem Einzeiler können wir den Mittelwert für jedes Element der Liste berechnen. Denk dran, dass das hier gut funktioniert hat, da die Elemente alle numerische Vektoren waren und der Mittelwert somit jedes Mal ohne Probleme berechnet werden kann. Wir können übrigens auch sapply benutzen, welches den Rückgabetypen vereinfacht (und somit keine Liste mehr ist): sapply(lstRating, mean). Wir können uns natürlich auch andere Statistiken berechnen lassen, zum Beispiel den Maximalwert: lapply(lstRating, max), den Minimalwert: lapply(lstRating, min), oder den Median: lapply(lstRating, median).

Grats! Nun weißt du über Listen in R Bescheid und dein R-Wissen ist somit um eine Grundlage reicher. Hast du noch Fragen? Oder zu einem ganz anderen Thema? Schreib mir einfach eine Mail: mail@r-coding.de.
Bleib außerdem auf dem Laufenden mit dem r-coding Newsletter. Du erhältst Infos zu neuen Blogeinträgen, sowie kleine Tipps und Tricks zu R. Melde dich jetzt an: http://r-coding.de/newsletter.

Add a comment

*Please complete all fields correctly

Ähnliche Posts

Plots in R
Objektstrukturen in R