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"


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow