Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ajouts conseils gestion RAM #335

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions 01_R_Insee/Fiche_utiliser_ressources.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,46 @@ La saturation de la mémoire vive est souvent provoquée par un utilisateur qui
| Fichier `.xls` | `read_excel()` | `readxl` | `n_max` |
| Fichier `.ods` | `read_ods()` | `readODS` | `range` |

### Choisir les classes de colonne les plus économes

Chaque colonne d'un `data.frame` a une classe qui sont plus ou moins gourmandes en mémoire. Grosso modo, dans `R`, les classes `integer`, `logical` et `factor` sont économes alors que les classes `numeric` et `character` prennent beaucoup de cases mémoires. Ainsi il est souvent recommandé de transformer une colonne de `character` en `factor` et de vérifier si une colonne de `numeric` ne peut pas être passée en `integer`.
Copy link
Contributor

@oliviermeslin oliviermeslin May 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Chaque colonne d'un `data.frame` a une classe qui sont plus ou moins gourmandes en mémoire. Grosso modo, dans `R`, les classes `integer`, `logical` et `factor` sont économes alors que les classes `numeric` et `character` prennent beaucoup de cases mémoires. Ainsi il est souvent recommandé de transformer une colonne de `character` en `factor` et de vérifier si une colonne de `numeric` ne peut pas être passée en `integer`.
Chaque colonne d'un `data.frame` a une classe qui définit sa nature informatique. Les principales classes de `R` sont les suivantes : `integer` (nombre entier), `numeric` (nombre réel), `character` (chaîne de caractères), `logical` (valeur logique) et `factor` (variable catégorielle). Or, certaines classes sont plus gourmandes en mémoire que d'autres. Dans `R`, les classes `integer`, `logical` et `factor` sont économes alors que les classes `numeric` et `character` utilisent davantage de mémoire. C'est pourquoi il peut être tuile de transformer une colonne de `character` en `factor` (avec la fonction `as.factor()`) et de vérifier si une colonne de classe `numeric` ne peut pas être transformée en `integer` (avec la fonction `as.integer()`).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Très bien, mais il manque des exemples simples. Suggestion: utiliser doremifasolData et le COG pour convertir des noms de communes/départements/régions en factor.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ben c'est marrant, il y aussi la recommandation exactement opposée dans la communauté R : éviter d'utiliser les factors car trop de chausse-trappe 😄
Content que stringsAsFactors soit passé à FALSE.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bien d'accord avec @RLesur ! Je hais les facteurs et ne les utilise que lorsque j'y suis obligé (faire du ggplot2, en l’occurrence). La différence entre la valeur sous-jacente et la valeur d'affichage est trop perturbante pour moi. Si on veut recommander l'utilisation des factor, il va falloir expliquer en détail comment les manipuler dans un autre endroit, parce que c'est loin d'être si évident que ça... (Notamment quand il faut les réordonner, quel enfer !)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@clerousset : que proposes-tu sur ce paragraphe? Ma reformulation te convient-elle?


### Eviter les valeurs manquantes inutiles

Une valeur manquante prend la même place en mémoire qu'une valeur non manquante. Il faut donc chercher à ne pas en abuser. Une valeur est manquante soit quand elle est en attente de remplissage (imputation statistique par exemple), soit quand la remplir serait absurde. Dans ce dernier cas, repenser la structure des bases peut être utile. Prenons une base individuelle contenant le nombre d'enfants de chacun et l'année de naissance des enfants. La structure de base suivante :

| id | nb_enfant | annee_naissance_enfant_1 |annee_naissance_enfant_2 | annee_naissance_enfant_3 | annee_naissance_enfant_4 |
|-|-|-|-|-|-|
| 1 | 4 | 1980 | 1982 | 1986 | 1990 |
| 2 | 1 | 1986 | NA | NA | NA |
| 3 | 0 | NA | NA | NA | NA |

est problématique car, par exemple, la colonne `annee_naissance_enfant_4` aura beaucoup de valeurs manquantes et prendra beaucoup de place pour peu d'informations.

La même information peut se mettre en deux bases :

* une individuelle réduite :

| id | nb_enfant |
|-|-|
| 1 | 4 |
| 2 | 1 |
| 3 | 0 |

* une spécifique aux années de naissance des enfants :

| id | annee_naissance_enfant |
|-|-|
| 1 | 1980 |
| 1 | 1982 |
| 1 | 1986 |
| 1 | 1990 |
| 2 | 1986 |

### Faire la chasse aux informations redondantes

Le fait que la base tienne dans la RAM permet d'accélérer les calculs. Aussi il est souvent préférable de réduire la taille de la base même au prix de quelques calculs supplémentaires. Par exemple supposons qu'on ait une colonne `date_naissance` qui soit au format `Date` et que, très souvent, on ait besoin de l'année naissance ou du mois de naissance de l'individu. Créer les colonnes `annee_naissance = year(dateNaissance)` et `mois_naissance = month(dateNaissance)` peut être tentant mais bien souvent la perte de RAM associée à ces deux nouvelles colonnes sera plus dommageable que l'inconvénient de devoir à chaque fois réécrire `year(dateNaissance)`, quitte à demander 30 fois à `R` de refaire ce petit calcul.
oliviermeslin marked this conversation as resolved.
Show resolved Hide resolved

### Faire preuve de prudence en faisant des jointures

Un autre cas standard de saturation de la mémoire vive provient d'une erreur dans la réalisation d'une jointure entre deux tables. En effet, une jointure mal réalisée peut aboutir à une table d'une taille largement supérieure à celle
Expand Down