R Language
listor
Sök…
Snabb introduktion till listor
Generellt sett brukar de flesta objekt du interagerar med som användare vara en vektor; t.ex. numerisk vektor, logisk vektor. Dessa objekt kan bara ta in en enda typ av variabel (en numerisk vektor kan bara ha siffror inuti).
En lista skulle kunna lagra alla typer av variabler i den, vilket gör det till det generiska objektet som kan lagra alla typer av variabler vi skulle behöva.
Exempel på initialisering av en lista
exampleList1 <- list('a', 'b')
exampleList2 <- list(1, 2)
exampleList3 <- list('a', 1, 2)
För att förstå de data som definierades i listan kan vi använda str-funktionen.
str(exampleList1)
str(exampleList2)
str(exampleList3)
Underavsättning av listor skiljer mellan att extrahera en bit av listan, dvs att få en lista som innehåller en delmängd av elementen i den ursprungliga listan, och att extrahera ett enda element. Att använda [
operatören som vanligtvis används för vektorer ger en ny lista.
# Returns List
exampleList3[1]
exampleList3[1:2]
För att få ett enda element använder du [[
istället.
# Returns Character
exampleList3[[1]]
Listposter kan namnges:
exampleList4 <- list(
num = 1:3,
numeric = 0.5,
char = c('a', 'b')
)
Posterna i namngivna listor kan nås med deras namn istället för deras index.
exampleList4[['char']]
Alternativt kan $
-operatören användas för att komma åt namngivna element.
exampleList4$num
Detta har fördelen att det är snabbare att skriva och kan vara lättare att läsa men det är viktigt att vara medveten om en potentiell fallgrop. $
-Operatören använder partiell matchning för att identifiera matchande listelement och kan ge oväntade resultat.
exampleList5 <- exampleList4[2:3]
exampleList4$num
# c(1, 2, 3)
exampleList5$num
# 0.5
exampleList5[['num']]
# NULL
Listor kan vara särskilt användbara eftersom de kan lagra objekt i olika längder och i olika klasser.
## 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
Introduktion till listor
Listor tillåter användare att lagra flera element (som vektorer och matriser) under ett enda objekt. Du kan använda list
funktion för att skapa en lista:
l1 <- list(c(1, 2, 3), c("a", "b", "c"))
l1
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "a" "b" "c"
Lägg märke till att vektorerna som utgör listan ovan är olika klasser. Listor tillåter användare att gruppera element från olika klasser. Varje element i en lista kan också ha ett namn. Listnamn öppnas av names
och tilldelas på samma sätt rad- och kolumnnamn tilldelas i en matris.
names(l1)
## NULL
names(l1) <- c("vector1", "vector2")
l1
## $vector1
## [1] 1 2 3
##
## $vector2
## [1] "a" "b" "c"
Det är ofta lättare och säkrare att förklara listnamnen när listobjektet skapas.
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"
Ovanför listan har två element, benämnda "vec" och "matta", en vektor och matris, resepcively.
Anledningar till att använda listor
För den genomsnittliga R-användaren kan liststrukturen tyckas vara en av de mer komplicerade datastrukturerna att manipulera. Det finns inga garantier för att alla element i den är av samma typ; Det finns ingen garanterad struktur för hur komplicerad / icke-komplicerad listan skulle vara (Ett element i en lista kan vara en lista)
Emellertid är en av de främsta orsakerna till när man använder listor för att använda den för att skicka parametrar mellan funktioner.
# 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)
I exemplet ovan är de returnerade resultaten bara enkla numeriska vektorer. Det finns inga problem att överföra så enkla vektorer.
Det är viktigt att notera vid denna punkt att i allmänhet R-funktioner bara returnerar 1 resultat åt gången (Du kan använda om villkoren för att returnera olika resultat). Men om du tänker skapa en funktion som tar en uppsättning parametrar och returnerar flera typer av resultat, till exempel en numerisk vektor (inställningsvärde) och en dataram (från beräkningen), måste du dumpa alla dessa resultat i en lista innan du returnerar den.
# 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]]
Konvertera en lista till en vektor medan du håller tomma listelement
När man vill konvertera en lista till en vektor eller data.frame-objekt tappas vanligtvis tomma element.
Detta kan vara problematiskt där en lista skapas med önskad längd skapas med några tomma värden (t.ex. skapas en lista med n-element för att läggas till en mxn-matris, data.frame eller data.table). Det är dock möjligt att förlustlöst konvertera en lista till en vektor, men bibehålla tomma element:
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
Serialisering: använda listor för att skicka information
Det finns fall där det är nödvändigt att sammanföra data av olika slag. I Azure ML är det till exempel nödvändigt att vidarebefordra information från en R-skriptmodul till en annan exklusivt genom dataram. Anta att vi har ett dataframe och ett 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"
Vi kan komma åt denna information:
> 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"
För att lägga till olika typer av data i ett dataframe måste vi använda listobjektet och serien. I synnerhet måste vi lägga upp data i en generisk lista och sedan lägga listan i en viss dataframe:
l <- list(df,number)
dataframe_container <- data.frame(out2 = as.integer(serialize(l, connection=NULL)))
När vi har lagrat informationen i dataframe måste vi deserialisera den för att använda den:
#----- 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]]
Sedan kan vi verifiera att informationen har överförts korrekt:
> 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"