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"


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow