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"


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow