[Résolu] Comparaison de cellules à partir d'un autre fichier

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Laëtitia VIBERT
Messages : 42
Enregistré le : 16 Avr 2019, 10:13

[Résolu] Comparaison de cellules à partir d'un autre fichier

Messagepar Laëtitia VIBERT » 16 Oct 2020, 16:23

Bonjour,
je dispose d'un jeu de données incluant (entre autres) une colonne avec des noms d'espèces, et des colonnes de mesures biométriques (longueur, masse etc) comme suit :

Code : Tout sélectionner

dataset <- structure(list(SP = structure(1:10, .Label = c("A", "C", "C", "B", "A", "A", "C", "B", "C", "A"), class = "factor"),
LENGTH = c(73.5, 17.6, 17.0, 30.9, 77.4, 76.0, 17.2, 32.2, 17.1, 74.4),
MASS = c(20.1, 5.4, 5.3, 10.2, 21.0, 21.2, 4.4, 30.0, 5.6, 19.9)),
.Names = c("SP", "LENGTH", "MASS"), row.names = c(NA,-10L), class = c("tbl_df", "tbl", "data.frame"))


Afin d'automatiser la vérification de la saisie, je souhaite faire une recherche automatique des valeurs aberrantes, en me basant sur les min et max de la longeur et de la masse pour chaque espèce.
Je suis capable de le faire avec des boucles "for()" et "if()", mais commençant à m'initier au data wrangling, je suis sûre qu'il existe un moyen bien plus clean, rapide et efficace pour réaliser cela (le tableau total comportant plusieurs centaines de milliers de lignes).
Je pensais d'abord charger un tableau comportant pour chaque espèce les min et max de longueur et masse, par exemple :

Code : Tout sélectionner

biometrie <- structure(list(SP = structure(1:3, .Label = c("A", "B", "C"), class = "factor"),
MinLength = c(74.2, 30.1, 16.5),
MaxLength = c(78.3, 35.1, 18.3),
MinMass = c(19.3, 9.8, 4.0),
MaxMass = c(22.1, 12.6, 5.6)),
.Names = c("SP", "MinLength", "MaxLength", "MinMass", "MaxMass"), row.names = c(NA,-3L), class = c("tbl_df", "tbl", "data.frame"))


Ainsi, il faudrait que pour chaque ligne, en fonction de l'espèce concernée, les cellules contenant des valeurs aberrantes (ici, en l'occurance, une longeur de 73.5 pour l'espèce A et une masse de 30.0 pour l'espèce B) apparaissent/soient stockées dans un fichier, ce qui permettrait ainsi d'aller modifier le fichier de base (voire peut-être même pourrait-on corriger directement sur le tbl?)

J'imagine qu'il faut utiliser des fonctions de comparaison, mais après plusieurs jours à me creuser les méninges, je sèche vraiment !

Merci grandement pour votre aide,

LV
L.

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Comparaison de cellules à partir d'un autre fichier

Messagepar Mickael Canouil » 19 Oct 2020, 14:54

Bonjour,

voici une proposition d'identification des lignes utilisant une jointure avec data.table (plus performant que le tidyverse) :

Code : Tout sélectionner

library(data.table)
dt <- as.data.table(biometrie)[
  as.data.table(dataset), 
  
.(LENGTH, MASS, is_outlier = !(between(LENGTH, MinLength, MaxLength) & between(MASS, MinMass, MaxMass))), 
  by 
= .EACHI,
  on = "SP"
]
dt[(is_outlier), .(SP, LENGTH, MASS)]
#>    SP LENGTH MASS
#> 1:  A   73.5 20.1
#> 2:  B   32.2 30.0  


Et "l'équivalent" dplyr

Code : Tout sélectionner

library(dplyr)
tbl <- left_join(= dataset, y = biometrie, by = "SP") %>% 
  rowwise
() %>% 
  mutate
(is_outlier = !(between(LENGTH, MinLength, MaxLength) & between(MASS, MinMass, MaxMass)))
tbl %>% 
  filter
(is_outlier) %>% 
  select
(SP, LENGTH, MASS)
#> # A tibble: 2 x 3
#> # Rowwise: 
#>   SP    LENGTH  MASS
#>   <fct>  <dbl> <dbl>
#> 1 A       73.5  20.1
#> 2 B       32.2  30  


Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

Laëtitia VIBERT
Messages : 42
Enregistré le : 16 Avr 2019, 10:13

Re: Comparaison de cellules à partir d'un autre fichier

Messagepar Laëtitia VIBERT » 22 Oct 2020, 13:08

Bonjour,

Excellent ! Merci, c'est parfaitement ce que je cherchais !
A vrai dire, j'avais fini par trouver qqch d'un peu similaire, avec left_join(), mais ne connaissant pas la formule between(), j'avais utilisé la différence LENGTH - MaxLength ou MinLength - LENGTH en affichant ensuite les lignes avec des valeurs < 0. Mais avec between() c'est plus clean et plus rapide =)

Merci encore !
L.


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité