2017-07-12 2 views
3

j'ai une trame de données telle que définie ci-dessous:colonne de trame de données Unlist et en les collant ensemble

df <- structure(list(ID = 1:19, MEDICATION = c("0", "NOVOMIX 26 BF, 20 D", 
               "NOVOMIX 14 D", "NOVOMIX 34 BF 22 D", "MIXTARD 52 BF 20 D", "MIXTARD 40 BF 24 D", 
               "MIXTARD 10 BF 8 D", "MIXTARD 42 BF 24 D", "MIXTARD 20 BF 18 D", 
               "MIXTARD 82 BF 46 D", "MIXTARD 14 BF 10 D", "NOVOMIX 15 BF 15 D", 
               "MIXTARD", NA, "MIXTARD 10 BF 4 D", "NOVOMIX", "MIXTARD --> NOVOMIX", 
               "NOT GIVEN ANY DIABETES MEDICATION INPATIENT PATIENT NORMALLY ON METFORMIN", 
               "GIVEN ASPART")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -19L), .Names = c("ID", "MEDICATION")) 

Je souhaite extraire tous les médicaments (par exemple NOVOMIX, MIXTARD, METFORMIN, ASPART de la variable MEDICATION dans la trame de données . et les coller ensemble, j'ai écrit mon code comme suit:

library(tidyverse) 
library(rebus) 
df %>% 
     mutate(MEDICATION2 = str_extract_all(MEDICATION, pattern = 
          or1(c("NOVOMIX", "MIXTARD", "METFORMIN", "ASPART")))) %>% 
     unnest(MEDICATION2) %>% 
     group_by(ID) %>% 
     mutate(MEDICATION2 = str_c(unlist(MEDICATION2), collapse = " - ")) %>% 
     slice(1) 

ma sortie est attendue:

df_out <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
13, 14, 15, 16, 17, 18, 19), MEDICATION = c("0", "NOVOMIX 26 BF, 20 D", 
"NOVOMIX 14 D", "NOVOMIX 34 BF 22 D", "MIXTARD 52 BF 20 D", "MIXTARD 40 BF 24 D", 
"MIXTARD 10 BF 8 D", "MIXTARD 42 BF 24 D", "MIXTARD 20 BF 18 D", 
"MIXTARD 82 BF 46 D", "MIXTARD 14 BF 10 D", "NOVOMIX 15 BF 15 D", 
"MIXTARD", NA, "MIXTARD 10 BF 4 D", "NOVOMIX", "MIXTARD --> NOVOMIX", 
"NOT GIVEN ANY DIABETES MEDICATION INPATIENT PATIENT NORMALLY ON METFORMIN", 
"GIVEN ASPART"), MEDICATION2 = c(NA, "NOVOMIX", "NOVOMIX", "NOVOMIX", 
"MIXTARD", "MIXTARD", "MIXTARD", "MIXTARD", "MIXTARD", "MIXTARD", 
"MIXTARD", "NOVOMIX", "MIXTARD", NA, "MIXTARD", "NOVOMIX", "MIXTARD - NOVOMIX", 
"METFORMIN", "ASPART")), .Names = c("ID", "MEDICATION", "MEDICATION2" 
), row.names = c(NA, -19L), class = "data.frame") 

Le problème est le code supprimé la ligne avec MEDICATION == 0 et je pense que mon code est trop long pour une extraction simple des chaînes. Je voudrais demander de l'aide si vous savez comment ce code peut être raccourci (si possible).

+0

Vous pouvez tout simplement faire quelque chose comme 'sapply (c ("NOVOMIX", "Mixtard", "METFORMINE", "ASPART"), grepl, x = df $ MEDICATION) 'pour obtenir 4 colonnes binaires, 1 pour chaque médicament. – thelatemail

+0

@thelatemail J'ai d'autres colonnes que j'aimerais conserver pendant que j'extrais les médicaments et je préférerais n'avoir qu'une seule variable pour le médicament. – HNSKD

Répondre

4

Nous pouvons utiliser stri_extract_all_regex à partir du package stringi pour extraire tous les mots correspondant au motif. Tel que mentionné par @ mt1022, la nouvelle colonne est une liste. Nous pouvons les paste avec

df$MEDICATION2<-paste(stri_extract_all_regex(df$MEDICATION,pattern = med_pattern)) 

Cependant, il ne donnera pas des caractères indésirables pour les listes avec plus de 1 élément. Cela devrait vous donner la sortie attendue.

chars <- stri_extract_all_regex(df$MEDICATION, pattern = med_pattern) 
df$MEDICATION2 <- sapply(chars, paste, collapse = "-") 
df$MEDICATION2 

#[1] "NA"    "NOVOMIX"   "NOVOMIX"   "NOVOMIX"   
#[5] "MIXTARD"   "MIXTARD"   "MIXTARD"   "MIXTARD"   
#[9] "MIXTARD"   "MIXTARD"   "MIXTARD"   "NOVOMIX"   
#[13] "MIXTARD"   "NA"    "MIXTARD"   "NOVOMIX"   
#[17] "MIXTARD-NOVOMIX" "METFORMIN"  "ASPART" 

Vous pouvez aussi le faire en une seule ligne:

df$MEDICATION2 <- sapply(stri_extract_all_regex(df$MEDICATION, 
         pattern = med_pattern), paste, collapse = "-") 
+0

La nouvelle colonne est une liste. vous pouvez coller chaque élément de la liste ensemble. – mt1022

+0

@ mt1022 à droite! Juste mis à jour la réponse. Merci :) –