• Aucun résultat trouvé

Modification des colonne

Dans le document Notes de cours de R - Version 2 (Page 148-156)

2.4 Manipulation des données

2.4.7 Data tables

2.4.7.6 Modification des colonne

Dans l’application de la fonction"[.data.table"()à undata.table, le deuxième argument peut être une ou plusieurs expressions dont les arguments sont les noms des colonnes du data.table, sans les guillemets.

Si on souhaite ajouter une nouvelle variable dans le data.table, on peut le faire avec le symbole d’assignation, ou bien en utilisant le symbole :=.

chomage[, a := letters[1:12]]

# Equivalent de

# chomage$temp <- letters[1:12]

L’ajout d’une nouvelle variable à partir des valeurs contenues dans ledata.tableest un peu plus subtil. Il faut utiliser le symbole := et il n’est plus possible d’utiliser la flèche<-. chomage[, b := ouvriers + ingenieurs]

L’ajout de plusieurs variables possède un syntaxe un peu moins intuitive.

chomage[, ":=" (c = ouvriers/100, d = paste0(a,b))]

Une fonctionnalité pratique est qu’il est possible de définir une variable et de la réutiliser directement après sa définition.

chomage[, c("e", "f") := list(tmp <- ouvriers + ingenieurs, round(sqrt(tmp)))]

La suppression se fait avecNULL, et il faut placer le nom des variables entouré de guillemets dans un vecteur.

# Suppression de plusieurs colonnes

chomage[, c("a", "b", "c", "d", "e") := NULL]

# Suppression d'une seule colonne chomage[, f := NULL]

2.4.7.7 Tri

Lorsqu’une clé est définie, les enregistrement du data.table sont triés en fonction de cette clé. Si la clé contient plusieurs noms de colonnes, par exemple var_1, var_2, etc., le tri s’effectue d’abord par la première variable (var_1), puis la seconde (var_2), etc.

Il est possible de forcer le tri sur une autre variable, ou plusieurs autres.

head(chomage[order(annee)])

## region departement annee ouvriers ingenieurs

## 1: Bretagne Cotes -d’Armor 2010 8113 1334

## 2: Bretagne Finistere 2010 12258 2401

## 3: Bretagne Ille -et - Vilaine 2010 10897 3776

## 4: Bretagne Morbihan 2010 9617 1979

## 5: Corse Corse -du - Sud 2010 936 253

## 6: Corse Haute - Corse 2010 1220 241

2.4.7.8 Copie de data.tables

Attention, pour copier un data.table, il faut utiliser la fonction copy()! En effet, la flèche d’assignation ne réalise pas la création d’une nouvelle variable dont le contenu est désigné par le bout de la flèche, elle réalise une référence.

dt <- data.table(x = letters[1:3], y = 4:6) dt

## x y

## 1: a 4

## 2: b 5

## 3: c 6

# Référence dt_ref <- dt

# Copie

dt_copie <- copy(dt)

# Ajoutons une variable dt[, a := rep(1,3)]

dt_ref[, z := paste0(x,y)]

dt_copie[, t := paste0(y,x)]

# Les variables "a" et "z" ont été ajoutées à dt et dt_ref

# sans impacter dt_copie

# La variable "t" n'a été ajoutée qu'à dt_copie dt

## x y a z

## 1: a 4 1 a4

## 2: b 5 1 b5

## 3: c 6 1 c6

dt_ref

## x y a z

## 1: a 4 1 a4

## 2: b 5 1 b5

## 3: c 6 1 c6

dt_copie

## x y t

## 1: a 4 4a

## 2: b 5 5b

## 3: c 6 6c

# En revanche, la suppression de dt_ref ne supprime pas dt rm(dt_ref)

Pour réaliser une jointure, on peut utiliser la fonction merge() (bien que non présentée dans ces notes, cette fonction s’applique aussi aux tibbles). Le package {data.table} fournit d’autres méthodes, plus rapides, en passant, encore une fois, par la fonction

"[.data.frame"(). La manière la plus simple, pour ne pas faire d’erreur lors de la jointure, est de définir en clé les variables communes aux deux tables.

setkey(chomage, region, annee) setkey(population, region, annee) chomage[population]

## region departement annee ouvriers ingenieurs population

## 1: Alsace <NA > 2010 NA NA 1845687

## 2: Alsace <NA > 2011 NA NA 1852325

## 3: Bretagne Cotes -d’Armor 2010 8113 1334 3199066

## 4: Bretagne Finistere 2010 12258 2401 3199066

## 5: Bretagne Ille -et - Vilaine 2010 10897 3776 3199066

## 6: Bretagne Morbihan 2010 9617 1979 3199066

## 7: Bretagne Cotes -d’Armor 2011 8738 1420 3217767

## 8: Bretagne Finistere 2011 12701 2530 3217767

## 9: Bretagne Ille -et - Vilaine 2011 11390 3986 3217767

## 10: Bretagne Morbihan 2011 10228 2025 3217767

On peut le voir, la jointure réalisée est de typeRight Join, c’est à dire que tous les éléments de la seconde table sont présents, mais que seuls ceux de la première à l’intersection avec la seconde sont conservés (on note que les observations concernant la Corse ont disparues).

Les diagrammes suivants donnent les autres fusions possibles. On peut remarquer que le Full Outer Join n’est pas possible avec la fonction "[.data.frame"().

p

population[chomage]

population[chomage, nonmatch = 0] merge(chomage, population, all = TRUE)

chomage[population]

Inner Join

Full Outer Join Left Outer Join

Right Outer Join

L’avantage, outre le temps gagné lorsqu’on a de gros volumes de données, d’utiliser

"[.data.frame"() plutôt que merge(), est aussi qu’il est possible de faire une opération juste après la jointure. On gagne à la fois en temps d’exécution, et en lignes de codes, ainsi qu’en clarté de lecture.

chomage[population][,round((ouvriers + ingenieurs)/population*100, 2)]

## [1] NA NA 0.30 0.46 0.46 0.36 0.32 0.47 0.48 0.38

chomage[population,

list(tmp = round((ouvriers + ingenieurs)/population*100, 2), departement)]

## tmp departement

## 1: NA <NA >

## 2: NA <NA >

## 3: 0.30 Cotes -d’Armor

## 4: 0.46 Finistere

## 5: 0.46 Ille -et - Vilaine

## 6: 0.36 Morbihan

## 7: 0.32 Cotes -d’Armor

## 8: 0.47 Finistere

## 9: 0.48 Ille -et - Vilaine

## 10: 0.38 Morbihan

Il arrive d’avoir à joindre des data.table en les empilant, par lignes. Une manière de faire passe par un simple appel à la fonctiondo.call(), avec en premier argument la fonction rbind(). Cela dit, cette méthode peut s’avérer prendre beaucoup de temps. La fonction rbindlist()propose de joindre par les lignes des tables de manière très rapide, à condition d’avoir les différentes parties à coller placées dans une liste.

l <- lapply(1:3, function(x) data.table(valeur = x, lettre = LETTERS[x])) res1 <- do.call("rbind", l)

res2 <- rbindlist(l)

all.equal(res1, res2)

## [1] TRUE

2.4.7.10 Agrégation

Pour obtenir le résultat d’une fonction appliquée à toute une colonne, il faut travailler avec le second argument de la fonction "[.data.table"().

chomage[, mean(ouvriers)]

## [1] 7364.167

Si on souhaite effectuer des regroupements, il faut rajouter l’argument by et lui atribuer le nom de la colonne (sans guillemets). Si le regroupement doit s’effectuer selon plusieurs colonnes, il faut alors envelopper les noms séparés par des virgules (mais sans espace) par des guillemets. On peut également fournir la liste des noms dans une liste, ce qui est un peu plus souple.

chomage[, mean(ouvriers), by = region]

## region V1

## 1: Bretagne 10492.75

## 2: Corse 1107.00

chomage[, mean(ouvriers), by = "region,departement"]

## region departement V1

## 1: Bretagne Cotes -d’Armor 8425.5

## 2: Bretagne Finistere 12479.5

## 3: Bretagne Ille -et - Vilaine 11143.5

## 4: Bretagne Morbihan 9922.5

## 5: Corse Corse -du - Sud 955.5

## 6: Corse Haute - Corse 1258.5

# Fournit le même résultat

# chomage[, mean(ouvriers), by = list(region, departement)]

Il est possible d’effectuer des calculs sur plusieurs des colonnes dudata.table. Pour ce faire, il faut placer le second argument de la fonction "[.data.table"() dans une liste. Si on souhaite donner des noms aux variables issues du calcul, c’est possible. Attention, il faut bien être dans une liste pour attribuer le nom !

chomage[, list(mean(ouvriers), sd(ouvriers)), by = region]

## region V1 V2

## 1: Bretagne 10492.75 1627.4581

## 2: Corse 1107.00 178.4507

# Ne permet pas d'attribuer le nom "moyenne" au calcul chomage[, moyenne = mean(ouvriers), by = region]

## Error in ‘[. data .table ‘( chomage , , moyenne = mean ( ouvriers ), by = region ): argument inutilis é ( moyenne = mean ( ouvriers ))

# Il faut être dans une liste

chomage[, list(moyenne = mean(ouvriers)), by = region]

## region moyenne

## 1: Bretagne 10492.75

## 2: Corse 1107.00

Les opérations de regroupement sont beaucoup plus rapides qu’avec les tibbles ou les data.frames (à condition d’avoir des volumes de données larges).

Par ailleurs, on peut effectuer plusieurs opérations d’un coup, qui dépendent des résultats précédents, en utilisant à nouveau la fonction "[.data.table"().

# Créons un data.table immense (presque 7 millions d'obs.)

# Après avoir calculé la moyenne de z pour chaque groupe

# défini par les valeurs de x et y,

# on ne conserve que les observations pour lesquelles la moyenne

# fraîchement créée est supérieure à 0.5

dt[, list(moy = mean(z)), by = "x,y"][moy > 0.5]

Le tableau ci-dessous répertorie quelques fonctions de base qu’il est bon de connaître pour manipuler les données dans R.

Fonction Description

x%%y Modulo

x%/%y Division entière

Dans le document Notes de cours de R - Version 2 (Page 148-156)