R Language
Des listes
Recherche…
Introduction rapide aux listes
En général, la plupart des objets avec lesquels vous interagiriez en tant qu’utilisateur auraient tendance à être un vecteur; par exemple, vecteur numérique, vecteur logique. Ces objets ne peuvent contenir qu'un seul type de variable (un vecteur numérique ne peut contenir que des chiffres).
Une liste serait capable de stocker n'importe quelle variable de type, en faisant à l'objet générique qui peut stocker n'importe quel type de variables dont nous aurions besoin.
Exemple d'initialisation d'une liste
exampleList1 <- list('a', 'b')
exampleList2 <- list(1, 2)
exampleList3 <- list('a', 1, 2)
Pour comprendre les données définies dans la liste, nous pouvons utiliser la fonction str.
str(exampleList1)
str(exampleList2)
str(exampleList3)
Le sous-ensemble de listes fait la distinction entre l'extraction d'une tranche de la liste, c'est-à-dire l'obtention d'une liste contenant un sous-ensemble des éléments de la liste d'origine et l'extraction d'un seul élément. L'utilisation de [
opérateur couramment utilisé pour les vecteurs produit une nouvelle liste.
# Returns List
exampleList3[1]
exampleList3[1:2]
Pour obtenir un seul élément, utilisez [[
place.
# Returns Character
exampleList3[[1]]
Les entrées de liste peuvent être nommées:
exampleList4 <- list(
num = 1:3,
numeric = 0.5,
char = c('a', 'b')
)
Les entrées dans les listes nommées sont accessibles par leur nom au lieu de leur index.
exampleList4[['char']]
L'opérateur $
peut également être utilisé pour accéder aux éléments nommés.
exampleList4$num
Cela a l'avantage d'être plus rapide à taper et peut être plus facile à lire, mais il est important d'être conscient d'un piège potentiel. L'opérateur $
utilise une correspondance partielle pour identifier les éléments de liste correspondants et peut produire des résultats inattendus.
exampleList5 <- exampleList4[2:3]
exampleList4$num
# c(1, 2, 3)
exampleList5$num
# 0.5
exampleList5[['num']]
# NULL
Les listes peuvent être particulièrement utiles car elles peuvent stocker des objets de différentes longueurs et de différentes classes.
## 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
Introduction aux listes
Les listes permettent aux utilisateurs de stocker plusieurs éléments (comme des vecteurs et des matrices) sous un seul objet. Vous pouvez utiliser la fonction de list
pour créer une liste:
l1 <- list(c(1, 2, 3), c("a", "b", "c"))
l1
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "a" "b" "c"
Notez que les vecteurs de la liste ci-dessus sont des classes différentes. Les listes permettent aux utilisateurs de regrouper des éléments de différentes classes. Chaque élément d'une liste peut également avoir un nom. Les noms de liste sont accessibles par la fonction de names
et sont attribués de la même manière que les noms de lignes et de colonnes sont affectés dans une matrice.
names(l1)
## NULL
names(l1) <- c("vector1", "vector2")
l1
## $vector1
## [1] 1 2 3
##
## $vector2
## [1] "a" "b" "c"
Il est souvent plus facile et plus sûr de déclarer les noms de liste lors de la création de l'objet de liste.
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"
Au-dessus de la liste, il y a deux éléments, nommés "vec" et "mat", un vecteur et une matrice, de manière respcente.
Raisons de l'utilisation des listes
Pour l'utilisateur R moyen, la structure de liste peut apparaître comme l'une des structures de données les plus compliquées à manipuler. Il n'y a aucune garantie que tous les éléments qu'il contient sont du même type; Il n'y a pas de structure garantie quant à la complexité / non-complication de la liste (Un élément dans une liste peut être une liste)
Cependant, l’une des principales raisons pour lesquelles il est nécessaire d’utiliser des listes pour transmettre des paramètres entre des fonctions.
# 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)
Dans l'exemple ci-dessus, les résultats renvoyés ne sont que de simples vecteurs numériques. Il n'y a pas de problèmes à passer sur de tels vecteurs simples.
Il est important de noter à ce stade que les fonctions R ne renvoient généralement qu'un résultat à la fois (vous pouvez utiliser des conditions if pour renvoyer des résultats différents). Toutefois, si vous avez l'intention de créer une fonction qui prend un ensemble de paramètres et renvoie plusieurs types de résultats tels qu'un vecteur numérique (valeur de paramètres) et un bloc de données (à partir du calcul), vous devrez exporter tous ces résultats dans une liste. avant de le retourner
# 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]]
Convertir une liste en vecteur tout en conservant des éléments de liste vides
Lorsque l'on souhaite convertir une liste en objet vectoriel ou data.frame, les éléments vides sont généralement supprimés.
Cela peut être problématique si une liste est créée avec la longueur souhaitée et est créée avec des valeurs vides (par exemple, une liste avec n éléments est créée pour être ajoutée à une matrice mxn, data.frame ou data.table). Il est toutefois possible de convertir sans perte une liste en vecteur, en conservant les éléments vides:
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
Sérialisation: utiliser des listes pour transmettre des informations
Il existe des cas dans lesquels il est nécessaire de rassembler des données de types différents. Dans Azure ML, par exemple, il est nécessaire de transmettre des informations d'un module de script R à un autre exclusivement via des cadres de données. Supposons que nous ayons un dataframe et un numéro:
> 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"
Nous pouvons accéder à ces informations:
> 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"
Afin de mettre différents types de données dans un dataframe, nous devons utiliser l'objet liste et la sérialisation. En particulier, nous devons mettre les données dans une liste générique et ensuite mettre la liste dans un fichier de données particulier:
l <- list(df,number)
dataframe_container <- data.frame(out2 = as.integer(serialize(l, connection=NULL)))
Une fois que nous avons stocké les informations dans le dataframe, nous devons les désérialiser pour les utiliser:
#----- 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]]
Ensuite, nous pouvons vérifier que les données sont correctement transférées:
> 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"