R Language
lijsten
Zoeken…
Snelle inleiding tot lijsten
Over het algemeen zijn de meeste objecten waarmee u als gebruiker interacteert, meestal een vector; bijv. numerieke vector, logische vector. Deze objecten kunnen slechts één type variabele bevatten (een numerieke vector kan alleen getallen bevatten).
Een lijst zou elk type variabele erin kunnen opslaan, waardoor het een generiek object wordt dat elk type variabelen kan opslaan die we nodig zouden hebben.
Voorbeeld van het initialiseren van een lijst
exampleList1 <- list('a', 'b')
exampleList2 <- list(1, 2)
exampleList3 <- list('a', 1, 2)
Om de gegevens te begrijpen die in de lijst zijn gedefinieerd, kunnen we de str-functie gebruiken.
str(exampleList1)
str(exampleList2)
str(exampleList3)
Bij het instellen van lijsten wordt onderscheid gemaakt tussen het extraheren van een deel van de lijst, dat wil zeggen het verkrijgen van een lijst met een subset van de elementen in de oorspronkelijke lijst, en het extraheren van een enkel element. Het gebruik van de [
operator die gewoonlijk wordt gebruikt voor vectoren levert een nieuwe lijst op.
# Returns List
exampleList3[1]
exampleList3[1:2]
Gebruik [[
plaats daarvan om een enkel element te verkrijgen.
# Returns Character
exampleList3[[1]]
Lijstvermeldingen kunnen worden genoemd:
exampleList4 <- list(
num = 1:3,
numeric = 0.5,
char = c('a', 'b')
)
De vermeldingen in benoemde lijsten zijn toegankelijk met hun naam in plaats van hun index.
exampleList4[['char']]
Als alternatief kan de $
-operator worden gebruikt om toegang te krijgen tot genoemde elementen.
exampleList4$num
Dit heeft het voordeel dat het sneller te typen is en misschien gemakkelijker te lezen is, maar het is belangrijk om op de hoogte te zijn van een mogelijke valkuil. De operator $
gebruikt gedeeltelijke overeenkomsten om overeenkomende elementen van de lijst te identificeren en kan onverwachte resultaten opleveren.
exampleList5 <- exampleList4[2:3]
exampleList4$num
# c(1, 2, 3)
exampleList5$num
# 0.5
exampleList5[['num']]
# NULL
Lijsten kunnen bijzonder nuttig zijn omdat ze objecten van verschillende lengtes en van verschillende klassen kunnen opslaan.
## 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
Inleiding tot lijsten
Lijsten stellen gebruikers in staat om meerdere elementen (zoals vectoren en matrices) onder een enkel object op te slaan. U kunt de list
gebruiken om een lijst te maken:
l1 <- list(c(1, 2, 3), c("a", "b", "c"))
l1
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "a" "b" "c"
Merk op dat de vectoren in de bovenstaande lijst verschillende klassen zijn. Lijsten stellen gebruikers in staat elementen van verschillende klassen te groeperen. Elk element in een lijst kan ook een naam hebben. Lijstnamen worden benaderd door de names
en worden op dezelfde manier toegewezen als rij- en kolomnamen in een matrix.
names(l1)
## NULL
names(l1) <- c("vector1", "vector2")
l1
## $vector1
## [1] 1 2 3
##
## $vector2
## [1] "a" "b" "c"
Het is vaak eenvoudiger en veiliger om de lijstnamen aan te geven bij het maken van het lijstobject.
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"
Boven de lijst heeft twee elementen, respectievelijk "vec" en "mat", een vector en matrix.
Redenen om lijsten te gebruiken
Voor de gemiddelde R-gebruiker kan de lijststructuur een van de meer gecompliceerde datastructuren lijken te zijn om te manipuleren. Er zijn geen garanties dat alle elementen erin van hetzelfde type zijn; Er is geen gegarandeerde structuur van hoe ingewikkeld / niet-ingewikkeld de lijst zou zijn (een element in een lijst kan een lijst zijn)
Een van de belangrijkste redenen om lijsten te gebruiken om parameters tussen functies door te geven.
# 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 het bovenstaande voorbeeld zijn de geretourneerde resultaten slechts eenvoudige numerieke vectoren. Er zijn geen problemen om dergelijke eenvoudige vectoren over te slaan.
Het is belangrijk op dit punt op te merken dat R-functies over het algemeen slechts 1 resultaat per keer retourneren (u kunt als voorwaarden gebruiken om verschillende resultaten te retourneren). Als u echter van plan bent een functie te maken die een set parameters gebruikt en verschillende soorten resultaten retourneert, zoals een numerieke vector (instellingswaarde) en een gegevensframe (uit de berekening), moet u al deze resultaten in een lijst dumpen voordat u het retourneert.
# 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]]
Converteer een lijst naar een vector met behoud van lege lijstelementen
Wanneer men een lijst naar een vector- of data.frame-object wil converteren, worden meestal lege elementen verwijderd.
Dit kan problematisch zijn, omdat een lijst met de gewenste lengte wordt gemaakt met enkele lege waarden (er wordt bijvoorbeeld een lijst met n-elementen gemaakt om toe te voegen aan een mxn-matrix, data.frame of data.table). Het is echter mogelijk om zonder verlies een lijst naar een vector te converteren, met lege elementen:
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
Serialisatie: lijsten gebruiken om informatie door te geven
Er zijn gevallen waarin het nodig is om gegevens van verschillende typen samen te voegen. In Azure ML is het bijvoorbeeld noodzakelijk om informatie van een R-scriptmodule door te geven aan een andere uitsluitend via dataframes. Stel dat we een dataframe en een nummer hebben:
> 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"
We hebben toegang tot deze informatie:
> 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"
Om verschillende soorten gegevens in een dataframe te plaatsen, moeten we het lijstobject en de serialisatie gebruiken. In het bijzonder moeten we de gegevens in een generieke lijst plaatsen en vervolgens de lijst in een bepaald dataframe plaatsen:
l <- list(df,number)
dataframe_container <- data.frame(out2 = as.integer(serialize(l, connection=NULL)))
Nadat we de informatie in het dataframe hebben opgeslagen, moeten we deze deserialiseren om deze te kunnen gebruiken:
#----- 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]]
Vervolgens kunnen we controleren of de gegevens correct zijn overgedragen:
> 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"