Remplacer NA par valeur d'intérêt (par individu)

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

Oriane Moyne
Messages : 17
Enregistré le : 20 Oct 2015, 15:50

Remplacer NA par valeur d'intérêt (par individu)

Messagepar Oriane Moyne » 20 Oct 2015, 16:23

Bonjour à tous,

Voici mon problème :
J'ai une base de données (data) concernant des prélèvements effectués par patient (une ligne par prélèvement, parfois plusieurs prélèvements par patient).

J'ai également une colonne "commentaires", avec une information lorsqu'elle est nécessaire (sinon NA).

en voici un extrait (anonymisé, chaque patient a un identifiant num_pat) :

num_pat Commentaires
1093 8 greffe - DCD
37 9 DCD
38 9 DCD
69 9 <NA>
71 9 <NA>
133 9 <NA>
200 9 <NA>
225 9 <NA>
226 9 <NA>
271 9 <NA>
292 9 <NA>
344 9 <NA>
345 9 <NA>
385 9 <NA>
394 9 <NA>
395 9 <NA>
416 9 <NA>
435 9 <NA>
436 9 <NA>
18 10 <NA>
19 10 <NA>
280 10 <NA>
351 10 <NA>
352 10 <NA>
353 10 <NA>
357 10 <NA>

Le problème, c'est que pour certains patients, j'ai parfois cette fameuse information, et parfois non. J'aimerais dans ce dernier cas remplacer les NA par l'information manquante...

Je me suis lancée dans la création d'une liste

Code : Tout sélectionner

parpat<-aggregate(data,by=list(data$num_pat),FUN=unique)


Puis j'ai compté le nombre d'informations distinctes par patient

Code : Tout sélectionner

parpat$comments<-sapply(parpat$Commentaires, length)


...Puis je me suis perdue dans des boucles sans fin pour essayer de remplacer, lorsqu'il y a 2 valeurs uniques (NA et une autre), le NA par la valeur d'intérêt.


Par exemple, j'ai tenté ça :

Code : Tout sélectionner

data$comment<-c()
i<-1
for (i in 1:nrow(data)){
  for(j in 1:nrow(parpat)){
    while(data$Patient[i]==parpat$Patient[j]){
      data$comment[i]<-ifelse(parpat$comments[j]>1, na.omit(parpat$Commentaires)[j], parpat$Commentaires[j])
            i<-i+1
    }
  }
}


Enfin voilà, c'est mon premier post, j'espère que vous allez comprendre mon problème !

Merci à celles et ceux qui tenterons de m'aider

jean lobry
Messages : 733
Enregistré le : 17 Jan 2008, 20:00
Contact :

Re: Remplacer NA par valeur d'intérêt (par individu)

Messagepar jean lobry » 20 Oct 2015, 20:08

Bonjour Oriane,

il faudrait un petit exemple reproductible, anonymisé, pour que l'on puisse t'aider sur ce forum.

Amicalement,

jean

Oriane Moyne
Messages : 17
Enregistré le : 20 Oct 2015, 15:50

Re: Remplacer NA par valeur d'intérêt (par individu)

Messagepar Oriane Moyne » 21 Oct 2015, 07:37

Bonjour,

Voici un extrait, classé par numéro patient (patients 40 à 45). On voit que par exemple, pour le patient 40, nous avons 2 prélèvements (2 lignes), mais que l'information "DCD" n'est retrouvée que pour un des prélèvements. Je la voudrais à chaque apparition du patient !
(à l'inverse, aucune information n'est disponible pour les patients 43 à 45, donc je voudrais garder NA (ou "RAS").

Code : Tout sélectionner

          num_pat                   Commentaires
611       40                         <NA>
1135      40                 DCD
1014      41                         <NA>
1136      41                         <NA>
1137      41                         <NA>
415       42          transfert 2012
513       42                         <NA>
514       42                         <NA>
612       42                         <NA>
128       43                         <NA>
308       43                         <NA>
354       43                         <NA>
375       43                         <NA>
387       44                         <NA>
1138      44                         <NA>
613       45                         <NA>
614       45                         <NA>
615       45                         <NA>
1045      45                         <NA>
1046      45                         <NA>
1047      45                         <NA>
1139      45                         <NA>
1140      45                         <NA>
1141      45                         <NA>
1142      45                         <NA>
1143      45                         <NA>


Donc dans ma liste agrégée par patient, ça donne :

Code : Tout sélectionner

parpat<-aggregate(data,by=list(data$num_pat),FUN=unique)
parpat[c(40:45),c(36, 28)]
   num_pat              Commentaires
40      40                  NA, DCD
41      41                       NA
42      42        transfert 2012, NA
43      43                       NA
44      44                       NA
45      45                       NA


Est-ce clair ?

Merci pour votre aide !

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

Re: Remplacer NA par valeur d'intérêt (par individu)

Messagepar Mickael Canouil » 21 Oct 2015, 08:41

Bonjour, j'ai une solution (pas très jolie)

Code : Tout sélectionner

dta <- structure(list(num_pat = c(40L, 40L, 41L, 41L, 41L, 42L, 42L,
42L, 42L, 43L, 43L, 43L, 43L, 44L, 44L, 45L, 45L, 45L, 45L, 45L,
45L, 45L, 45L, 45L, 45L, 45L), Commentaires = c(NA, "DCD", NA,
NA, NA, "transfert 2012", NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("num_pat",
"Commentaires"), row.names = c(NA, -26L), class = "data.frame")


Faut-il garder le NA dans les commentaires, si une information existe? Si non, voici ma proposition:

Code : Tout sélectionner

dta2 <- do.call("rbind",
    by(dta, dta[, "num_pat"], function (idta) {
        if (!all(is.na(idta[, "Commentaires"]))) {
            idta[, "Commentaires"] <- paste(idta[which(!is.na(idta[, "Commentaires"])), "Commentaires"], collapse = ";")
        } else {}
        return(idta)
    })
)


Code : Tout sélectionner

R> unique(dta2)
      num_pat   Commentaires
40.1       40            DCD
41.3       41           <NA>
42.6       42 transfert 2012
43.10      43           <NA>
44.14      44           <NA>
45.16      45           <NA>

R> dta2
      num_pat   Commentaires
40.1       40            DCD
40.2       40            DCD
41.3       41           <NA>
41.4       41           <NA>
41.5       41           <NA>
42.6       42 transfert 2012
42.7       42 transfert 2012
42.8       42 transfert 2012
42.9       42 transfert 2012
43.10      43           <NA>
43.11      43           <NA>
43.12      43           <NA>
43.13      43           <NA>
44.14      44           <NA>
44.15      44           <NA>
45.16      45           <NA>
45.17      45           <NA>
45.18      45           <NA>
45.19      45           <NA>
45.20      45           <NA>
45.21      45           <NA>
45.22      45           <NA>
45.23      45           <NA>
45.24      45           <NA>
45.25      45           <NA>
45.26      45           <NA>
Mickaël
mickael.canouil.fr | rlille.fr

Oriane Moyne
Messages : 17
Enregistré le : 20 Oct 2015, 15:50

Re: Remplacer NA par valeur d'intérêt (par individu)

Messagepar Oriane Moyne » 21 Oct 2015, 09:31

Bonjour Mikael, et merci pour ta réponse !

Effectivement, ta solution marche, même si je n'ai pas très bien compris comment...

Code : Tout sélectionner

dta2 <- do.call("rbind",
    by(dta, dta[, "num_pat"], function (idta) {
        if (!all(is.na(idta[, "Commentaires"]))) {
            idta[, "Commentaires"] <- paste(idta[which(!is.na(idta[, "Commentaires"])), "Commentaires"], collapse = ";")
        } else {}
        return(idta)
    })
)


En gros, on crée une nouvelle data.frame en appliquant une fonction "idta", uniquement lorsqu'il n'y a pas que des NA dans les Commentaires associés au patient ?

Je n'ai pas bien compris la fonction en elle-même :

Code : Tout sélectionner

idta[, "Commentaires"] <- paste(idta[which(!is.na(idta[, "Commentaires"])), "Commentaires"], collapse = ";")

Pouvez-vous me l'expliquer ?


Pour certains patients, j'ai des erreurs : l'information est répétée. Exemple ici (à droite, j'ai copié la colonne qui nous intéresse avant d'appliquer la fonction) :

Code : Tout sélectionner

data[c(324:349), c(35, 27, 34)]
        num_pat                                                Commentaires             Commentaires.2
36.16        36                                       suivi xxxx;suivi xxxx      suivi xxxx
36.17        36                                       suivi xxxx;suivi xxxx      suivi xxxx
36.144       36                                       suivi xxxx;suivi xxxx      <NA>
36.145       36                                       suivi xxxx;suivi xxxx      <NA>
37           37                                                        <NA>                      <NA>
38.1132      38 Transfert xxxxx2014;Transfert xxxxx2014;Transfert xxxxx2014       Transfert xxxxx2014
38.1133      38 Transfert xxxxx2014;Transfert xxxxx2014;Transfert xxxxx2014       Transfert xxxxx2014
38.1134      38 Transfert xxxxx2014;Transfert xxxxx2014;Transfert xxxxx2014       Transfert xxxxx2014
39.498       39                                                        <NA>                      <NA>
39.969       39                                                        <NA>                      <NA>
39.970       39                                                        <NA>                      <NA>
40.611       40                                                Pas xxxxxxxx                      <NA>
40.1135      40                                                Pas xxxxxxxx              Pas xxxxxxxx
41.1014      41                                                        <NA>                      <NA>
41.1136      41                                                        <NA>                      <NA>
41.1137      41                                                        <NA>                      <NA>
42.415       42                                         transfert xxxxx2012       transfert xxxxx2012
42.513       42                                         transfert xxxxx2012                      <NA>
42.514       42                                         transfert xxxxx2012                      <NA>
42.612       42                                         transfert xxxxx2012                      <NA>
43.128       43                                                        <NA>                      <NA>
43.308       43                                                        <NA>                      <NA>
43.354       43                                                        <NA>                      <NA>
43.375       43                                                        <NA>                      <NA>
44.387       44                                                        <NA>                      <NA>
44.1138      44                                                        <NA>                      <NA>


J'ai remplacé certains caractères par des xxx, mais ce sont bien les mêmes dans chaque "répétition"...

Cordialement,

Oriane

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

Re: Remplacer NA par valeur d'intérêt (par individu)

Messagepar Mickael Canouil » 21 Oct 2015, 09:45

Code : Tout sélectionner

do.call("rbind",
    by(dta, dta[, "num_pat"], function (idta) {
    ...
    })
)

Le "by" fonctionne sur le même principe que "aggregate".
La "function (idta) {...}" fonctionne sur un sous ensemble de la matrice dta, définie selon le facteur dta[, "num_pat"]. Ainsi idta est une matrice contenant toutes les lignes d'un patient.

Code : Tout sélectionner

idta[, "Commentaires"] <- paste(
    idta[which(!is.na(idta[, "Commentaires"])), "Commentaires"],
    collapse = ";"
)

"paste" permet de coller des chaines de caractères, avec l'option collapse pour concaténer les éléments d'un vecteur (ici la colonne "Commentaires")

Code : Tout sélectionner

which(!is.na(idta[, "Commentaires"]))

Ce morceau permet de récupérer les indices dans le vecteur idta[, "Commentaires"] où il n'y a pas de NA.


Pour certains patients, j'ai des erreurs : l'information est répétée. Exemple ici (à droite, j'ai copié la colonne qui nous intéresse avant d'appliquer la fonction) :

Pour régler cela, il suffit de demander à ne coller que les valeurs uniques:

Code : Tout sélectionner

idta[, "Commentaires"] <- paste(
    unique(idta[which(!is.na(idta[, "Commentaires"])), "Commentaires"]),
    collapse = ";"
)
Mickaël
mickael.canouil.fr | rlille.fr

Oriane Moyne
Messages : 17
Enregistré le : 20 Oct 2015, 15:50

Re: Remplacer NA par valeur d'intérêt (par individu)

Messagepar Oriane Moyne » 21 Oct 2015, 09:58

YES !

ça fonctionne, et j'ai compris comment !

Merci beaucoup pour votre aide


Retourner vers « Questions en cours »

Qui est en ligne

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