tableau avec plusieurs lignes pour une référence

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

Charles Marcucci
Messages : 52
Enregistré le : 13 Juil 2016, 09:00

tableau avec plusieurs lignes pour une référence

Messagepar Charles Marcucci » 04 Aoû 2017, 07:43

Bonjour,

J'ai un ensemble de dataframe de patient avec un dataframe avec une ligne = 1 patient et avec des informations spécifiques (DDN , poids , ...)
J'ai un second dataframe (EItab) avec les effets indésirables des patients. Par respect de confidentialité pour les patients ne mettrait que le nom des colonnes du dataframe.

Code : Tout sélectionner

[1] "STUDY_ID"        "COUNTRY_ID"      "EXTRACTION_DATE" "SITE_ID"         "SUBJECT_ID"     
 [6] "SUBJECT_REF"     "REF_NUMBER"      "REF_INITN"       "REF_INITP"       "MODULE_EI"     
[11] "FORM"            "FORM_EITAB"      "eiterm"          "EITERMP"         "EIGRADE"       
[16] "EISTDT_D"        "EISTDT_M"        "EISTDT_Y"        "EISTDT"          "EIEVOL"         
[21] "EIGRAV"          "EIENDT_D"        "EIENDT_M"        "EIENDT_Y"        "EIENDT"         
[26] "EIHOSPYN"        "HOSPSTDT_D"      "HOSPSTDT_M"      "HOSPSTDT_Y"      "HOSPSTDT"       
[31] "HOSPNDT_D"       "HOSPNDT_M"       "HOSPNDT_Y"       "HOSPNDT"         "EITRTYN"       
[36] "EITRTPYN"        "Ref"         


Je dois à la fin obtenir un seul dataframe avec une seule ligne par patient. Ce dataframe ce nomme stat
Le problème c'est que pour 1 patient je peux avoir 0,1,2,3.. lignes d'effets indésirables.
Donc j'ai écris le code suivant pour donc transformer mes lignes d'effets indésirables en une seul ligne

Code : Tout sélectionner

compteur_Rep=0
Date_Start_EI<-paste(EItab$EISTDT_D,EItab$EISTDT_M,EItab$EISTDT_Y,sep="-")
Date_Fin_EI<-paste(EItab$EIENDT_D,EItab$EIENDT_M,EItab$EIENDT_Y,sep="-")
Date_Debut_Hosp<-paste(EItab$HOSPSTDT_D,EItab$HOSPSTDT_M,EItab$HOSPSTDT_Y,sep="-")
Date_fin_Hosp<-paste(EItab$HOSPNDT_D,EItab$HOSPNDT_M,EItab$HOSPNDT_Y,sep="-")

for (i in 1:nrow(EItab)){
  if (i==1){
    stat[EItab$REF_NUMBER[i],82]<- as.character(EItab$FORM[i])
    stat[EItab$REF_NUMBER[i],83]<- as.character(EItab$eiterm[i])
    stat[EItab$REF_NUMBER[i],84]<-as.numeric(EItab$EIGRADE[i])
    stat[EItab$REF_NUMBER[i],85]<-Date_Start_EI[i]
    stat[EItab$REF_NUMBER[i],86]<-as.character(EItab$EIEVOL[i])
    stat[EItab$REF_NUMBER[i],87]<-as.character(EItab$EIGRAV[i])
    stat[EItab$REF_NUMBER[i],88]<-Date_Fin_EI[i]
    stat[EItab$REF_NUMBER[i],89]<-as.character(EItab$EIHOSPYN[i])
    stat[EItab$REF_NUMBER[i],90]<-Date_Debut_Hosp[i]
    stat[EItab$REF_NUMBER[i],91]<-Date_fin_Hosp[i]
    stat[EItab$REF_NUMBER[i],92]<-as.character(EItab$EITRTYN[i])
    stat[EItab$REF_NUMBER[i],93]<-as.character(EItab$EITRTPYN[i])
   
  }
  else{
    if(EItab$REF_NUMBER[i]!=EItab$REF_NUMBER[i-1])
    {
      compteur_Rep=0
      stat[EItab$REF_NUMBER[i],82]<- as.character(EItab$FORM[i])
      stat[EItab$REF_NUMBER[i],83]<- as.character(EItab$eiterm[i])
      stat[EItab$REF_NUMBER[i],84]<-as.numeric(EItab$EIGRADE[i])
      stat[EItab$REF_NUMBER[i],85]<-Date_Start_EI[i]
      stat[EItab$REF_NUMBER[i],86]<-as.character(EItab$EIEVOL[i])
      stat[EItab$REF_NUMBER[i],87]<-as.character(EItab$EIGRAV[i])
      stat[EItab$REF_NUMBER[i],88]<-Date_Fin_EI[i]
      stat[EItab$REF_NUMBER[i],89]<-as.character(EItab$EIHOSPYN[i])
      stat[EItab$REF_NUMBER[i],90]<-Date_Debut_Hosp[i]
      stat[EItab$REF_NUMBER[i],91]<-Date_fin_Hosp[i]
      stat[EItab$REF_NUMBER[i],92]<-as.character(EItab$EITRTYN[i])
      stat[EItab$REF_NUMBER[i],93]<-as.character(EItab$EITRTPYN[i])
     
     
    } else {
      compteur_Rep=compteur_Rep+12
      stat[EItab$REF_NUMBER[i],82+compteur_Rep]<- as.character(EItab$FORM[i])
      stat[EItab$REF_NUMBER[i],83+compteur_Rep]<- as.character(EItab$eiterm[i])
      stat[EItab$REF_NUMBER[i],84+compteur_Rep]<-as.numeric(EItab$EIGRADE[i])
      stat[EItab$REF_NUMBER[i],85+compteur_Rep]<-Date_Start_EI[i]
      stat[EItab$REF_NUMBER[i],86+compteur_Rep]<-as.character(EItab$EIEVOL[i])
      stat[EItab$REF_NUMBER[i],87+compteur_Rep]<-as.character(EItab$EIGRAV[i])
      stat[EItab$REF_NUMBER[i],88+compteur_Rep]<-Date_Fin_EI[i]
      stat[EItab$REF_NUMBER[i],89+compteur_Rep]<-as.character(EItab$EIHOSPYN[i])
      stat[EItab$REF_NUMBER[i],90+compteur_Rep]<-Date_Debut_Hosp[i]
      stat[EItab$REF_NUMBER[i],91+compteur_Rep]<-Date_fin_Hosp[i]
      stat[EItab$REF_NUMBER[i],92+compteur_Rep]<-as.character(EItab$EITRTYN[i])
      stat[EItab$REF_NUMBER[i],93+compteur_Rep]<-as.character(EItab$EITRTPYN[i])
     
    }}}
compteur_Rep=0
for (i in 1:5){
stat[,85+compteur_Rep]<-as.Date(stat[,85+compteur_Rep],format = "%d-%m-%Y")
stat[,88+compteur_Rep]<-as.Date(stat[,88+compteur_Rep],format = "%d-%m-%Y")
stat[,90+compteur_Rep]<-as.Date(stat[,90+compteur_Rep],format = "%d-%m-%Y")
stat[,91+compteur_Rep]<-as.Date(stat[,91+compteur_Rep],format = "%d-%m-%Y")
compteur_Rep=compteur_Rep+12
}


Ma question est la suivante : existe-il un moyen plus simple pour faire cette opération.

Merci d'avance

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: tableau avec plusieurs lignes pour une référence

Messagepar Logez Maxime » 04 Aoû 2017, 09:28

Bonjour,

Ca va un peu dans le sens de ce que je te disais pour la proposition de section. Sans exemple de données, il est difficile de savoir ce que tu attends, et le code est long à lire d'où la difficulté de proposer quelque chose de "plus adapter" par rapport à ce que tu veux faire.

Cordialement,
Maxime

Charles Marcucci
Messages : 52
Enregistré le : 13 Juil 2016, 09:00

Re: tableau avec plusieurs lignes pour une référence

Messagepar Charles Marcucci » 04 Aoû 2017, 10:05

Merci Maxime

J'ai comprend le problème on va faire plus simple alors

Code : Tout sélectionner

donnee<-data.frame(REF_NUMBER=1:5,Age=50:54,poids=90:94)
REF_NUMBER Age poids
1          1  50    90
2          2  51    91
3          3  52    92
4          4  53    93
5          5  54    94
EI<-data.frame(REF_NUMBER=sample(1:5,10,replace = T),FORM=c("EICUT","EIGI","EIPULM")[sample(1:3,10,replace = T)])
   REF_NUMBER   FORM
1           3   EIGI
2           2 EIPULM
3           5  EICUT
4           1  EICUT
5           5 EIPULM
6           2  EICUT
7           3  EICUT
8           5   EIGI
9           4  EICUT
10          5   EIGI



et j’aimerai obtenir le résultat suivant

Code : Tout sélectionner

  REF_NUMBER Age poids FORM_1 FORM_2
1          1  50    90  EICUT       
2          2  51    91 EIPULM  EICUT
3          3  52    92   EIGI  EICUT
4          4  53    93  EICUT       
5          5  54    94  EICUT   EIGI


j'arrive à le faire avec une boucle

Code : Tout sélectionner


for (i in 1:max(table(EI$REF_NUMBER)))
{
  donnee[,ncol(RFM)+1]<-NA
  names(donnee)[ncol(donnee)]<-paste("FORM_",i,sep="")
}

compteur_Rep=0
for (i in 1:nrow(EI)){
  if (i==1){
    donnee[EI$REF_NUMBER[i],4]<- as.character(EI$FORM[i])
  }
  else{
    if(EI$REF_NUMBER[i]!=EI$REF_NUMBER[i-1])
    {
    compteur_Rep=0
      donnee[EI$REF_NUMBER[i],4]<- as.character(EI$FORM[i])
    } else {
    compteur_Rep=compteur_Rep+1
      donnee[EI$REF_NUMBER[i],4+compteur_Rep]<- as.character(EI$FORM[i])
     
    }}}




mais est-qu'il y a une autre maniéré de procédé ?

Merci d'avance

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: tableau avec plusieurs lignes pour une référence

Messagepar Pierre-Yves Berrard » 04 Aoû 2017, 17:55

Une partie du problème peut-être résolu de la même façon qu'un sujet posté hier (par une autre personne !) :

Code : Tout sélectionner

library(tidyr)
library(dplyr)

EI2 <-
  EI %>%
  group_by(REF_NUMBER) %>%
  mutate(FORM_ = 1:n()) %>%
  spread(FORM_, FORM, sep = "")


Une fois la transformation préalable réalisée, c'est une simple appariement :

Code : Tout sélectionner

left_join(donnee, EI2, by = "REF_NUMBER")
PY

Charles Marcucci
Messages : 52
Enregistré le : 13 Juil 2016, 09:00

Re: tableau avec plusieurs lignes pour une référence

Messagepar Charles Marcucci » 07 Aoû 2017, 06:04

Je vais essayer d'adapter le code pour la situation où on a plusieurs colonne par exemple

Code : Tout sélectionner

EI<-data.frame(REF_NUMBER=sample(1:5,10,replace = T),FORM=c("EICUT","EIGI","EIPULM")[sample(1:3,10,replace = T)],Popo=sample(1:5,10,replace = T))

  REF_NUMBER   FORM Popo
1           4   EIGI    1
2           2   EIGI    1
3           4 EIPULM    3
4           3   EIGI    1
5           4 EIPULM    1
6           2   EIGI    3
7           5  EICUT    5
8           2 EIPULM    4
9           2  EICUT    2
10          3 EIPULM    5


et donc avoir les colonnes FORM_1, Popo_1, FORM_2 ..

Merci beaucoup en tout cas

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: tableau avec plusieurs lignes pour une référence

Messagepar Logez Maxime » 07 Aoû 2017, 08:05

Bonjour,

tu peux aussi faire ça avec les fonctions de base. Dans le cas avec plusieurs colonnes je trouve qu'il n'y a rien de plus efficace que la fonction reshape :

Code : Tout sélectionner

EI$FORM_N <- with(EI, ave(REF_NUMBER, REF_NUMBER, FUN = seq_along))

EIw <- reshape(EI, v.names = c("FORM", "Popo"), idvar = "REF_NUMBER", timevar = "FORM_N", direction = "wide")
EIw <- EIw[c(1, seq(2, ncol(EIw), 2), seq(3, ncol(EIw), 2))]

donnee2 <- merge(donnee, EIw, all.x = TRUE, by = "REF_NUMBER")
Cordialement,
Maxime

Charles Marcucci
Messages : 52
Enregistré le : 13 Juil 2016, 09:00

Re: tableau avec plusieurs lignes pour une référence

Messagepar Charles Marcucci » 07 Aoû 2017, 08:36

J'était entrain de decouvrir la fonction reshape mais merci beaucoup en tout cas

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: tableau avec plusieurs lignes pour une référence

Messagepar Logez Maxime » 07 Aoû 2017, 09:47

re,

avec tidyr c'est possible aussi (https://stackoverflow.com/questions/305 ... with-tidyr) mais je trouve ça beaucoup plus compliqué et au final pas très efficace (pour ce que j'arrive à faire) :

Code : Tout sélectionner

donnee %>% left_join(EI %>% group_by(REF_NUMBER) %>% mutate(FORM_N = 1:n()) %>%
  gather(variable, value, -c(1,4)) %>%
    unite(temp, variable, FORM_N) %>%
      spread(temp, value))
Cordialement,
Maxime

Charles Marcucci
Messages : 52
Enregistré le : 13 Juil 2016, 09:00

Re: tableau avec plusieurs lignes pour une référence

Messagepar Charles Marcucci » 07 Aoû 2017, 10:14

Merci beaucoup
j'avais commencer à faire avec ce package mais j'ai du mal a comprendre les fonctions gather et spread.
J'ai lu les description des fonctions mais je n'arrive pas à les manipuler.

Je comprend bien que la fonction gather permet de passer sur un mode "cle-valeur" mais je ne comprend pas son fonctionnement ni les arguments (car ici les argument ne correspondent en aucun cas à des variables de mon tableau, et je ne comprend pas la fonction du -c(1,4)( je sais que ça permet de sélectionner les colonnes 1 et 4 mais je ne comprend pas son role en tant qu'argument))

Est-ce que quelqu'un peux m'expliquer les lignes de code et/ou le fonctionnement de la fonction gather() ?


Merci d'avance

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: tableau avec plusieurs lignes pour une référence

Messagepar Logez Maxime » 07 Aoû 2017, 12:04

Le but de la fonction gather est de regrouper dans une seule colonne (value) des données qui sont stockées dans plusieurs et d'indiquer leur provenance (key) dans une autre colonne.

Code : Tout sélectionner

tab <- data.frame(A = 1:5, B = letters[1:5])
tab
  A B
1 1 a
2 2 b
3 3 c
4 4 d
5 5 e
gather(tab, origine, valeurs)
   origine valeurs
1        A       1
2        A       2
3        A       3
4        A       4
5        A       5
6        B       a
7        B       b
8        B       c
9        B       d
10       B       e
Ici on regroupe toutes les valeurs dans une seule colonne : valeurs (argument value). Les noms des colonnes dans lesquelles elles étaient stockées au préalable sera stocké dans la colonne origine (argument origine). Tout ce qui vient après l'argument value, permet de spécifier les colonnes qui seront regroupées. La logique du choix des colonnes est celle de la fonction select. Donc -c(1,4) permet d'exclure la première et la 4ème colonne dans le regroupement. Les valeurs contenues dans ces colonnes seront répétées autant de fois que nécessaire, pour conserver toute l'information originelle.

Code : Tout sélectionner

tab <- cbind(Z = sprintf("Ind_%s", 1:5), tab)
gather(tab, origine, valeurs)
   origine valeurs
1        Z   Ind_1
2        Z   Ind_2
3        Z   Ind_3
4        Z   Ind_4
5        Z   Ind_5
6        A       1
7        A       2
8        A       3
9        A       4
10       A       5
11       B       a
12       B       b
13       B       c
14       B       d
15       B       e
# par défaut toutes les colonnes sont regroupées en une seule.
# si tu ne veux pas que que la première colonne soit intégrée dans le regroupement :
gather(tab, origine, valeurs, -1)
       Z origine valeurs
1  Ind_1       A       1
2  Ind_2       A       2
3  Ind_3       A       3
4  Ind_4       A       4
5  Ind_5       A       5
6  Ind_1       B       a
7  Ind_2       B       b
8  Ind_3       B       c
9  Ind_4       B       d
10 Ind_5       B       e

# ou encore
gather(tab, origine, valeurs, 2:3)
gather(tab, origine, valeurs, matches("[A-B]"))
gather(tab, origine, valeurs, matches("[^Z]"))
# etc.
Cordialement,
Maxime

Charles Marcucci
Messages : 52
Enregistré le : 13 Juil 2016, 09:00

Re: tableau avec plusieurs lignes pour une référence

Messagepar Charles Marcucci » 09 Aoû 2017, 11:03

bonjour

Merci pour cette explication extrêmement claire j'ai beaucoup mieux compris

cordialement


Retourner vers « Questions en cours »

Qui est en ligne

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