R Language
Listen
Suche…
Schnelle Einführung in die Listen
Im Allgemeinen sind die meisten Objekte, mit denen Sie als Benutzer interagieren würden, tendenziell ein Vektor. zB numerischer Vektor, logischer Vektor. Diese Objekte können nur einen einzigen Variablentyp aufnehmen (ein numerischer Vektor kann nur Zahlen enthalten).
Eine Liste kann jede Typvariable darin speichern und sie zu einem generischen Objekt machen, das jeden Typ von Variablen speichern kann, die wir benötigen.
Beispiel für das Initialisieren einer Liste
exampleList1 <- list('a', 'b')
exampleList2 <- list(1, 2)
exampleList3 <- list('a', 1, 2)
Um die in der Liste definierten Daten zu verstehen, können wir die str-Funktion verwenden.
str(exampleList1)
str(exampleList2)
str(exampleList3)
Bei der Teilauswahl von Listen unterscheidet man zwischen dem Extrahieren eines Slice der Liste, dh dem Abrufen einer Liste mit einer Teilmenge der Elemente in der ursprünglichen Liste und dem Extrahieren eines einzelnen Elements. Wenn Sie den Operator [
, der üblicherweise für Vektoren verwendet wird, wird eine neue Liste erstellt.
# Returns List
exampleList3[1]
exampleList3[1:2]
Um ein einzelnes Element zu erhalten, verwenden Sie stattdessen [[
.
# Returns Character
exampleList3[[1]]
Listeneinträge können benannt werden:
exampleList4 <- list(
num = 1:3,
numeric = 0.5,
char = c('a', 'b')
)
Auf die Einträge in benannten Listen kann über ihren Namen statt über ihren Index zugegriffen werden.
exampleList4[['char']]
Alternativ kann mit dem Operator $
auf benannte Elemente zugegriffen werden.
exampleList4$num
Dies hat den Vorteil, dass es schneller zu tippen ist und möglicherweise einfacher zu lesen ist, aber es ist wichtig, dass Sie sich einer möglichen Fallstricke bewusst sind. Der Operator $
verwendet partielle Übereinstimmung, um übereinstimmende Listenelemente zu identifizieren, und kann zu unerwarteten Ergebnissen führen.
exampleList5 <- exampleList4[2:3]
exampleList4$num
# c(1, 2, 3)
exampleList5$num
# 0.5
exampleList5[['num']]
# NULL
Listen können besonders nützlich sein, da sie Objekte unterschiedlicher Länge und verschiedener Klassen speichern können.
## Numeric vector
exampleVector1 <- c(12, 13, 14)
## Character vector
exampleVector2 <- c("a", "b", "c", "d", "e", "f")
## Matrix
exampleMatrix1 <- matrix(rnorm(4), ncol = 2, nrow = 2)
## List
exampleList3 <- list('a', 1, 2)
exampleList6 <- list(
num = exampleVector1,
char = exampleVector2,
mat = exampleMatrix1,
list = exampleList3
)
exampleList6
#$num
#[1] 12 13 14
#
#$char
#[1] "a" "b" "c" "d" "e" "f"
#
#$mat
# [,1] [,2]
#[1,] 0.5013050 -1.88801542
#[2,] 0.4295266 0.09751379
#
#$list
#$list[[1]]
#[1] "a"
#
#$list[[2]]
#[1] 1
#
#$list[[3]]
#[1] 2
Einführung in die Listen
Listen ermöglichen Benutzern das Speichern mehrerer Elemente (wie Vektoren und Matrizen) unter einem einzigen Objekt. Sie können die list
verwenden, um eine Liste zu erstellen:
l1 <- list(c(1, 2, 3), c("a", "b", "c"))
l1
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "a" "b" "c"
Beachten Sie, dass die Vektoren, die die obige Liste bilden, unterschiedliche Klassen sind. Listen ermöglichen Benutzern das Gruppieren von Elementen verschiedener Klassen. Jedes Element in einer Liste kann auch einen Namen haben. Auf Listennamen wird von der names
zugegriffen und in derselben Weise Zeilen- und Spaltennamen in einer Matrix zugewiesen.
names(l1)
## NULL
names(l1) <- c("vector1", "vector2")
l1
## $vector1
## [1] 1 2 3
##
## $vector2
## [1] "a" "b" "c"
Es ist oft einfacher und sicherer, die Listennamen beim Erstellen des Listenobjekts anzugeben.
l2 <- list(vec = c(1, 3, 5, 7, 9),
mat = matrix(data = c(1, 2, 3), nrow = 3))
l2
## $vec
## [1] 1 3 5 7 9
##
## $mat
## [,1]
## [1,] 1
## [2,] 2
## [3,] 3
names(l2)
## [1] "vec" "mat"
Über der Liste befinden sich zwei Elemente, "vec" und "mat", ein Vektor und eine Matrix.
Gründe für die Verwendung von Listen
Für den durchschnittlichen R-Benutzer kann die Listenstruktur als eine der komplizierteren zu manipulierenden Datenstrukturen erscheinen. Es gibt keine Garantie dafür, dass alle Elemente des gleichen Typs sind. Es gibt keine garantierte Struktur dafür, wie kompliziert / nicht kompliziert die Liste wäre (Ein Element in einer Liste könnte eine Liste sein)
Einer der Hauptgründe, warum Listen verwendet werden, um Parameter zwischen Funktionen zu übergeben.
# Function example which returns a single element numeric vector
exampleFunction1 <- function(num1, num2){
result <- num1 + num2
return(result)
}
# Using example function 1
exampleFunction1(1, 2)
# Function example which returns a simple numeric vector
exampleFunction2 <- function(num1, num2, multiplier){
tempResult1 <- num1 + num2
tempResult2 <- tempResult1 * multiplier
result <- c(tempResult1, tempResult2)
return(result)
}
# Using example function 2
exampleFunction2(1, 2, 4)
In dem obigen Beispiel handelt es sich bei den zurückgegebenen Ergebnissen nur um einfache numerische Vektoren. Es gibt keine Probleme, über solche einfachen Vektoren hinwegzugehen.
Beachten Sie an dieser Stelle, dass R-Funktionen im Allgemeinen nur jeweils 1 Ergebnis zurückgeben (Sie können if-Bedingungen verwenden, um andere Ergebnisse zurückzugeben). Wenn Sie jedoch eine Funktion erstellen möchten, die einen Parametersatz übernimmt und verschiedene Arten von Ergebnissen zurückgibt, z. B. einen numerischen Vektor (Einstellungswert) und einen Datenrahmen (aus der Berechnung), müssen Sie alle diese Ergebnisse in einer Liste speichern bevor Sie es zurückschicken.
# We will be using mtcars dataset here
# Function which returns a result that is supposed to contain multiple type of results
# This can be solved by putting the results into a list
exampleFunction3 <- function(dataframe, removeColumn, sumColumn){
resultDataFrame <- dataframe[, -removeColumn]
resultSum <- sum(dataframe[, sumColumn])
resultList <- list(resultDataFrame, resultSum)
return(resultList)
}
# Using example function 3
exampleResult <- exampleFunction3(mtcars, 2, 4)
exampleResult[[1]]
exampleResult[[2]]
Konvertieren Sie eine Liste in einen Vektor, wobei leere Listenelemente leer bleiben
Wenn Sie eine Liste in ein Vektor- oder data.frame-Objekt konvertieren möchten, werden normalerweise leere Elemente gelöscht.
Dies kann problematisch sein, wenn eine Liste mit einer gewünschten Länge mit einigen leeren Werten erstellt wird (z. B. wird eine Liste mit n Elementen erstellt, die einer mxn-Matrix, data.frame oder data.table hinzugefügt wird). Es ist möglich, eine Liste verlustlos in einen Vektor zu konvertieren, wobei leere Elemente erhalten bleiben:
res <- list(character(0), c("Luzhuang", "Laisu", "Peihui"), character(0),
c("Anjiangping", "Xinzhai", "Yongfeng"), character(0), character(0),
c("Puji", "Gaotun", "Banjingcun"), character(0), character(0),
character(0))
res
[[1]] character(0) [[2]] [1] "Luzhuang" "Laisu" "Peihui" [[3]] character(0) [[4]] [1] "Anjiangping" "Xinzhai" "Yongfeng" [[5]] character(0) [[6]] character(0) [[7]] [1] "Puji" "Gaotun" "Banjingcun" [[8]] character(0) [[9]] character(0) [[10]] character(0)
res <- sapply(res, function(s) if (length(s) == 0) NA_character_ else paste(s, collapse = " "))
res
[1] NA "Luzhuang Laisu Peihui" NA "Anjiangping Xinzhai Yongfeng" NA [6] NA "Puji Gaotun Banjingcun" NA NA NA
Serialisierung: Verwenden von Listen zur Weitergabe von Informationen
Es gibt Fälle, in denen Daten unterschiedlichen Typs zusammengestellt werden müssen. In Azure ML müssen beispielsweise Informationen aus einem R-Skriptmodul ausschließlich über Datenrahmen an ein anderes übergeben werden. Angenommen, wir haben einen Datenrahmen und eine Nummer:
> df
name height team fun_index title age desc Y
1 Andrea 195 Lazio 97 6 33 eccellente 1
2 Paja 165 Fiorentina 87 6 31 deciso 1
3 Roro 190 Lazio 65 6 28 strano 0
4 Gioele 70 Lazio 100 0 2 simpatico 1
5 Cacio 170 Juventus 81 3 33 duro 0
6 Edola 171 Lazio 72 5 32 svampito 1
7 Salami 175 Inter 75 3 30 doppiopasso 1
8 Braugo 180 Inter 79 5 32 gjn 0
9 Benna 158 Juventus 80 6 28 esaurito 0
10 Riggio 182 Lazio 92 5 31 certezza 1
11 Giordano 185 Roma 79 5 29 buono 1
> number <- "42"
Wir können auf diese Informationen zugreifen:
> paste(df$name[4],"is a",df3$team[4], "supporter." )
[1] "Gioele is a Lazio supporter."
> paste("The answer to THE question is", number )
[1] "The answer to THE question is 42"
Um verschiedene Datentypen in einem Datenrahmen zu speichern, müssen wir das Listenobjekt und die Serialisierung verwenden. Insbesondere müssen wir die Daten in eine generische Liste einfügen und dann die Liste in einen bestimmten Datenrahmen einfügen:
l <- list(df,number)
dataframe_container <- data.frame(out2 = as.integer(serialize(l, connection=NULL)))
Nachdem wir die Informationen im Datenrahmen gespeichert haben, müssen wir sie deserialisieren, um sie verwenden zu können:
#----- unserialize ----------------------------------------+
unser_obj <- unserialize(as.raw(dataframe_container$out2))
#----- taking back the elements----------------------------+
df_mod <- unser_obj[1][[1]]
number_mod <- unser_obj[2][[1]]
Dann können wir überprüfen, ob die Daten korrekt übertragen werden:
> paste(df_mod$name[4],"is a",df_mod$team[4], "supporter." )
[1] "Gioele is a Lazio supporter."
> paste("The answer to THE question is", number_mod )
[1] "The answer to THE question is 42"