R Language
elenchi
Ricerca…
Introduzione rapida alle liste
In generale, la maggior parte degli oggetti con cui interagiresti come utente tenderebbe ad essere un vettore; ad esempio, il vettore numerico, il vettore logico. Questi oggetti possono contenere solo un singolo tipo di variabile (un vettore numerico può avere solo numeri al suo interno).
Una lista sarebbe in grado di memorizzare qualsiasi variabile di tipo in essa, rendendola all'oggetto generico in grado di memorizzare qualsiasi tipo di variabile di cui avremmo bisogno.
Esempio di inizializzazione di una lista
exampleList1 <- list('a', 'b')
exampleList2 <- list(1, 2)
exampleList3 <- list('a', 1, 2)
Per comprendere i dati che sono stati definiti nella lista, possiamo usare la funzione str.
str(exampleList1)
str(exampleList2)
str(exampleList3)
La suddivisione di elenchi distingue tra l'estrazione di una sezione dell'elenco, ovvero l'ottenimento di un elenco contenente un sottoinsieme degli elementi nell'elenco originale e l'estrazione di un singolo elemento. Usando [
operatore comunemente usato per i vettori produce una nuova lista.
# Returns List
exampleList3[1]
exampleList3[1:2]
Per ottenere un singolo elemento usa [[
invece.
# Returns Character
exampleList3[[1]]
Le voci della lista possono essere nominate:
exampleList4 <- list(
num = 1:3,
numeric = 0.5,
char = c('a', 'b')
)
È possibile accedere alle voci negli elenchi denominati in base al loro nome anziché al loro indice.
exampleList4[['char']]
In alternativa, l'operatore $
può essere utilizzato per accedere agli elementi denominati.
exampleList4$num
Questo ha il vantaggio che è più veloce da digitare e può essere più facile da leggere, ma è importante essere consapevoli di una potenziale trappola. L'operatore $
utilizza la corrispondenza parziale per identificare gli elementi della lista corrispondente e può produrre risultati imprevisti.
exampleList5 <- exampleList4[2:3]
exampleList4$num
# c(1, 2, 3)
exampleList5$num
# 0.5
exampleList5[['num']]
# NULL
Le liste possono essere particolarmente utili perché possono memorizzare oggetti di diverse lunghezze e di varie classi.
## 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
Introduzione alle liste
Le liste consentono agli utenti di memorizzare più elementi (come vettori e matrici) sotto un singolo oggetto. Puoi usare la funzione list
per creare un elenco:
l1 <- list(c(1, 2, 3), c("a", "b", "c"))
l1
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "a" "b" "c"
Si noti che i vettori che compongono l'elenco precedente sono classi diverse. Le liste consentono agli utenti di raggruppare elementi di classi diverse. Ogni elemento in una lista può anche avere un nome. I nomi delle liste sono accessibili tramite la funzione dei names
e sono assegnati nello stesso modo in cui i nomi delle righe e delle colonne sono assegnati in una matrice.
names(l1)
## NULL
names(l1) <- c("vector1", "vector2")
l1
## $vector1
## [1] 1 2 3
##
## $vector2
## [1] "a" "b" "c"
È spesso più facile e sicuro dichiarare i nomi delle liste quando si crea l'oggetto elenco.
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"
Sopra la lista ci sono due elementi, chiamati "vec" e "mat", un vettore e una matrice, in modo ricettivo.
Motivi per l'utilizzo di elenchi
Per l'utente R medio, la struttura delle liste potrebbe sembrare quella delle strutture di dati più complicate da manipolare. Non ci sono garanzie che tutti gli elementi al suo interno siano dello stesso tipo; Non esiste una struttura garantita di quanto complicato / non complicato sarebbe l'elenco (Un elemento in una lista potrebbe essere una lista)
Tuttavia, uno dei motivi principali per utilizzare gli elenchi per usarlo per passare i parametri tra le funzioni.
# 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)
Nell'esempio sopra, i risultati restituiti sono semplici vettori numerici. Non ci sono problemi per trasmettere questi semplici vettori.
È importante notare a questo punto che, in generale, le funzioni R restituiscono solo 1 risultato alla volta (è possibile utilizzare se le condizioni restituiscono risultati diversi). Tuttavia, se si intende creare una funzione che accetta un insieme di parametri e restituisce diversi tipi di risultati come un vettore numerico (valore delle impostazioni) e un frame di dati (dal calcolo), è necessario scaricare tutti questi risultati in un elenco prima di restituirlo.
# 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]]
Converti una lista in un vettore mantenendo gli elementi della lista vuota
Quando si desidera convertire una lista in un vettore o in un oggetto data.frame, gli elementi vuoti vengono generalmente eliminati.
Questo può essere problematico che viene creato un elenco di una lunghezza desiderata con alcuni valori vuoti (ad esempio viene creata una lista con n elementi da aggiungere a una matrice mxn, data.frame o data.table). Tuttavia, è possibile convertire senza perdita una lista in un vettore, mantenendo gli elementi vuoti:
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
Serializzazione: utilizzo delle liste per passare informazioni
Esistono casi in cui è necessario mettere insieme i dati di tipi diversi. Ad esempio, in Azure ML è necessario passare informazioni da un modulo di script R a un altro esclusivamente attraverso i dataframes. Supponiamo di avere un dataframe e un numero:
> 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"
Possiamo accedere a queste informazioni:
> 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"
Per inserire diversi tipi di dati in un dataframe dobbiamo usare l'oggetto lista e la serializzazione. In particolare, dobbiamo inserire i dati in un elenco generico e quindi inserire l'elenco in un dato dataframe:
l <- list(df,number)
dataframe_container <- data.frame(out2 = as.integer(serialize(l, connection=NULL)))
Una volta memorizzate le informazioni nel dataframe, è necessario deserializzare per utilizzarlo:
#----- 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]]
Quindi, possiamo verificare che i dati siano stati trasferiti correttamente:
> 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"