Fandom

Scratchpad

Sélectionner les lignes possédant la valeur maximum d'une variable

216,199pages on
this wiki
Add New Page
Discuss this page0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Soit un data frame possédant au moins deux variables, l'une identifiant au moins partiellement les enregistrements et l'autre étant une valeur numérique. Soit IDRecord et Var ces deux variables. Un même Idrecord peut être présent plusieurs fois, Var pouvant alors être à chaque fois différente ou bien une valeur déjà rencontrée. On veut filtrer les enregistrements du data set en ne conservant que les valeurs maximum pour chaque IDRecord à concurence maximum d'un enregistrement par IDRecord.

Une première approche consiste à utiliser l'opérateur max() conjointement à tapply(), by() ou aggregate(), en général à renommer la variable contenant les max à filtrer le data set initial en utilisant merge() en ayant pris soin que Var soit de type numeric (cf. Merge() de numeric et character). Cependant si pour un IDRecord donné il existe plusieurs fois la valeur maximum alors on aura non pas une seule ligne par IDRecord, mais autant de ligne qu'on a de maximum. Ce problème, qui n'est sans doute pas le seul, met en évidence que l'approche choisie pour résoudre le problème n'est pas adaptée.

Le verbe "filtrer" m'a amené à penser le problème comme réellement une sélection de lignes à l'aide d'un vecteur logique ce qui m'a amené à une solution du type :

 FiltreMax <- function(DataIn){
 # Conserve les enregistrements possédant la valeur max du champs Valeur au 
 # regard de la clé key.
   key <- c("Identifiant.point","Date.station","Code.taxon.dénombré")
   DuplicatedKeys <- unique(DataIn[duplicated(DataIn[,key]),key])
   
   # Enregistrements non dupliqués
   DataIn00 <- DataIn[!(paste(DataIn$Identifiant.point
                                   ,DataIn$Date.station
                                   ,DataIn$Code.taxon.dénombré) %in%
                               paste(DuplicatedKeys$Identifiant.point
                                   ,DuplicatedKeys$Date.station
                                   ,DuplicatedKeys$Code.taxon.dénombré)),]
   
   # Enregistrements dupliqués
   DataIn01 <- DataIn[(paste(DataIn$Identifiant.point
                                   ,DataIn$Date.station
                                   ,DataIn$Code.taxon.dénombré) %in%
                               paste(DuplicatedKeys$Identifiant.point
                                   ,DuplicatedKeys$Date.station
                                   ,DuplicatedKeys$Code.taxon.dénombré)),]
   
   # Je ne garde que les valeurs max. D'abord un tri : 
   DataIn01 <- DataIn01[order(DataIn01$Identifiant.point
                                   ,DataIn01$Date.station
                                   ,DataIn01$Code.taxon.dénombré),]
   
   # Construction du vecteur logique.
   # Attention : l'ordre de la liste doit être inversé par rapport au tri.
   Filtre <- unlist(by(DataIn01
                       ,list(
                             Code.taxon.dénombré = DataIn01$Code.taxon.dénombré
                             ,Date.station=DataIn01$Date.station
                             ,Identifiant.point = DataIn01$Identifiant.point
                             )
                         ,function(x) pmatch(as.numeric(x$Valeur),max(as.numeric(x$Valeur)),nomatch=0) > 0
                       ))
   
   DataIn02 <- DataIn01[Filtre,]
   
   DataIn03 <- rbind(DataIn00,DataIn02)
   
   return(DataIn03)
 }

La difficulté résidant uniquement dans :

 function(x) pmatch(as.numeric(x$Valeur),max(as.numeric(x$Valeur)),nomatch=0) > 0

où pmatch() va marquer d'un "1" la première valeur égale au max, d'un 0 toutes les autres, les éléments du vecteur résultant étant aussitôt comparés à "0" et les issues logique de ces comparaisons en vecteur logique des lignes à garder et à "jeter". Si la difficulté est là, en revanche il faut bien faire attention à l'ordre des variables lors du tri préalable ainsi qu'à l'ordre de ces variables lors de la construction du vecteur logique.

Also on Fandom

Random wikia