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"


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow