Dataframes avancés.
Sélection de lignes ou colonnes d'un dataframe :
- subset(fr, nom == "jean") : sélectione le sous dataframe en retenant les lignes dont la colonne nom vaut "jean" (ca peut être une expression plus complexe comme subset(fr, nom %in% c("pierre", "jean"))
- fr[which(fr$nom == "jean"), ] : autre façon de faire la même sélection.
- fr[fr$nom == "jean", ] : encore une autre façon de faire la même sélection.
- subset(fr, select = c(age)) : sélectione le sous dataframe en retenant les colonnes indiquées (sans quotes !)
- subset(fr, select = - c(age)) : sélectione le sous dataframe en enlevant les colonnes indiquées.
Sélection de lignes avec des expressions booléennes :
- fr[fr$nom == "jean" | ! fr$age > 35, ] : combinaison de critères (avec opérateurs booléens '|', '&' et '!')
- subset(fr, nom == "jean" | ! age > 35) : autre façon.
Elimination des doublons dans un dataframe : grâce à unique :
fr <- data.frame(A = factor(c("a", "b", "a")), B = c(3, 4, 3))
unique(fr)
A B
1 a 3
2 b 4
Calcul d'agrégats par groupe avec by :
- Si fr <- data.frame(typ = factor(c("a", "b", "b", "a", "b")), val = c(3, 5, 2, 3, 1)), alors res <- by(fr$val, fr$typ, sum) : calcule la somme des valeurs de val par valeur de typ.
- Le résultat est un objet de type by (une liste) : par exemple, res[["a"]] ou res[[1]] donne 6.
Calcul d'agrégats par groupe avec aggregate (beaucoup plus commode) :
- aggregate(fr$val, by = list(typ2 = fr$typ), sum) : calcule aussi la somme des valeurs de val par valeur de typ, mais renvoie un objet de type dataframe.
typ2 x 1 a 6 2 b 8
- On peut donner une fonction quelconque, y compris anonyme : aggregate(fr$val, by = list(typ = fr$typ), function(vect) {sqrt(sum(vect ^ 2))}).
- Pour éviter que la colonne d'agrégat porte le nom de x et lui donner le nom que l'on souhaite : aggregate(data.frame(somme = fr$val), by = list(typ2 = fr$typ), sum).
- Le paramètre "by" peut prendre une liste de plusieurs colonnes pour faire un agrégat selon plusieurs colonnes.
fr <- data.frame(typ = factor(c("a", "b", "b", "a", "b")), typ2 = factor(c("A", "B", "B", "B", "B")), val = c(3, 5, 2, 3, 1)) aggregate(data.frame(val = fr$val), by = list(typ = fr$typ, typ2 = fr$typ2), mean)donne :typ typ2 val 1 a A 3.000000 2 a B 3.000000 3 b B 2.666667
Passage d'un dataframe avec 2 facteurs à une matrice, avec aggrégation des valeurs au passage (souvent avec moyenne) :
fr <- data.frame(typ = factor(c("a", "b", "b", "a", "b")),
typ2 = factor(c("A", "B", "B", "B", "B")),
val = c(3, 5, 2, 3, 1))
tapply(fr$val, list(typ = fr$typ, typ2 = fr$typ2), mean)
donne
typ2 typ A B a 3 3.000000 b NA 2.666667le résultat est une matrice.
Jointure de frames (au sens relationnel) :
Si fr1 <-data.frame(val1 = c("a", "b"), val2 = c(2, 4)); fr2 <- data.frame(val2 = c(2, 3, 4), val3 = c("b", "c", "a")) :
- merge(fr1, fr2) : fait une jointure sur les colonnes qui ont même nom (il peut y en avoir plusieurs).
val2 val1 val3 1 2 a b 2 4 b a
- merge(fr1, fr2, by = c("val2")) : précise les noms des colonnes sur lesquelles on fait la jointure (si on ne veut en utiliser qu'une partie).
- merge(fr1, fr2, by.x = c("val1"), by.y = c("val3")) : indique dque l'on doit faire la jointure sur d'autre colonnes que celles de même nom dans chaque frame (val1 côté fr1 et val3 côté fr2).
val1 val2.x val2.y 1 a 2 4 2 b 4 2
- merge(fr1, fr2, by.x = 1, by.y = 2) : idem, mais en précisant le numéro des colonnes plutôt que leur nom.
- merge(fr1, fr2, all = TRUE) : fait une jointure externe des deux côtés (conserve les lignes qui n'ont pas de correspondance dans l'autre frame en rajoutant des NA dans les cases indéterminées :
val2 val1 val3 1 2 a b 2 3 <NA> c 3 4 b a
- merge(fr1, fr2, all.y = TRUE) : fait une jointure externe seulement du côté du 2ème dataframe (all.x = TRUE pour le premier dataframe).
Stacking/unstacking de frames :
- fr2 <- stack(fr) : pour transformer un dataframe avec plusieurs colonnes en dataframe avec seulement 2 colonnes : le nom de la colonne de départ et la valeur :
ctrl trt1 trt2 1 4.3 4.2 6.3 2 4.5 4.7 6.1
devient :values ind 1 4.3 ctrl 2 4.5 ctrl 3 4.2 trt1 4 4.7 trt1 5 6.3 trt2 6 6.1 trt2
- Opération inverse de destacking : unstack(fr2, values ~ ind) : redonne le frame de départ dans le cas ci-dessus.
Transformation d'une matrice en data-frame à colonnes avec les noms des lignes et des colonnes de la matrice et les valeurs :
mat <- matrix(c(1, 2, 3, 4, 5, 6), nrow = 3,
dimnames = list(c("A", "B", "C"), c("a", "b")))
print(mat)
fr <- data.frame(varLine = rep(rownames(mat), times = ncol(mat)),
varColumn = rep(colnames(mat), each = nrow(mat)),
values = as.vector(mat))
print(fr)
donne :
a b A 1 4 B 2 5 C 3 6 varLine varColumn values 1 A a 1 2 B a 2 3 C a 3 4 A b 4 5 B b 5 6 C b 6
Split de valeurs selon un facteur :
Si fr est le dataframe :
typ val 1 a 3 2 b 5 3 b 2 4 a 3 5 b 1split(fr$val, fr$typ) : partage les valeurs de fr$val selon les valeurs de fr$typ pour donner une liste dont les éléments sont les vecteurs de valeurs de fr$val par valeur de fr$typ :
$a [1] 3 3 $b [1] 5 2 1
