J'ai un ensemble de données avec un très grand nombre de variables de colonne de chaîne représentant des codes de procédure. Il y a une autre colonne de variables qui représente le format de codage (certaines sont ICD9, d'autres sont d'autres formats plus obscurs). Chaque observation est un patient. Je dois:
Il y a trop de variables pour qu'il soit trivial de créer une liste de chacune d'elles manuellement via c ("cd1", "cd2", ...), et j'ai potentiellement besoin de faire autant différentes fois, j'aimerais donc en faire une solution aussi générale que possible.
Voici un exemple simplifié, où les chaînes que je dois rechercher commencent par "231":
df <- df %>% mutate_at(vars(starts_with("cd")), funs(testvar = ifelse(startsWith(., "231"), 1, 0))) test_names = df %>% select(ends_with("_testvar")) %>% names() df <- df %>% mutate(flag_var = (rowSums(.[test_names]) == 1)) df <- df %>% select(-ends_with("_testvar"))
Le résultat que je voudrais est:
df <- df %>% mutate(flag_var = case_when( startsWith(cd1, "231") ~ 1, startsWith(cd2, "231") ~ 1, startsWith(cd3, "231") ~ 1, startsWith(cd4, "231") ~ 1, TRUE ~ 0))
(l'ID # 5 est mis à 0 car, même si le code cd1 est "231" , la variable type1 est "01" et donc pas dans le bon format de codage ")
J'ai quelque peu réussi à accomplir cela en utilisant mutate et case_when:
ID cd1 type1 cd2 type2 cd3 type3 cd4 type4 flag_var 1 "231" "02" "219" "02" "1321" "02" "2314" "02" 1 2 "222" "02" 0 3 "123" "142" 0 4 "145" "02" "521" "02" "2313" "02" 1 5 "231" "01" 0
3 Réponses :
Cela peut répondre à la question ou avez-vous besoin de 0-1 comme valeurs de ligne?
dat %>% gather("cd_type", "code", 2:5) %>% mutate(flag_var = case_when( startsWith(code, "231") ~ 1, TRUE ~ 0 )) %>% spread(cd_type, code) %>% select(ID, cd1:cd4, flag_var) #> # A tibble: 6 x 6 #> ID cd1 cd2 cd3 cd4 flag_var #> <dbl> <chr> <chr> <chr> <chr> <dbl> #> 1 1 <NA> 219 1321 <NA> 0 #> 2 1 231 <NA> <NA> 2314 1 #> 3 2 222 "" "" "" 0 #> 4 3 123 142 "" "" 0 #> 5 4 145 521 <NA> 122 0 #> 6 4 <NA> <NA> 2313 <NA> 1
Ou faites-le pour revenir au grand format d'origine
library(tidyverse) dat <- tribble(~ID, ~cd1, ~cd2, ~cd3, ~cd4, 1, "231", "219", "1321", "2314", 2, "222", "" , "" , "", 3, "123", "142", "" , "", 4, "145", "521", "2313", "122") dat %>% gather("cd_type", "code", 2:5) %>% mutate(flag_var = case_when( startsWith(code, "231") ~ 1, TRUE ~ 0 )) #> # A tibble: 16 x 4 #> ID cd_type code flag_var #> <dbl> <chr> <chr> <dbl> #> 1 1 cd1 231 1 #> 2 2 cd1 222 0 #> 3 3 cd1 123 0 #> 4 4 cd1 145 0 #> 5 1 cd2 219 0 #> 6 2 cd2 "" 0 #> 7 3 cd2 142 0 #> 8 4 cd2 521 0 #> 9 1 cd3 1321 0 #> 10 2 cd3 "" 0 #> 11 3 cd3 "" 0 #> 12 4 cd3 2313 1 #> 13 1 cd4 2314 1 #> 14 2 cd4 "" 0 #> 15 3 cd4 "" 0 #> 16 4 cd4 122 0
Merci, cela semble être une méthode élégante. Vous pouvez voir à partir de votre exemple que cela ne renvoie pas les données inchangées. Les identifiants n ° 1 et n ° 4 ont désormais chacun deux observations lorsque les données sont renvoyées au format large. Le formulaire final de l'ensemble de données doit rester inchangé par rapport à la façon dont il a commencé, sauf avec l'ajout d'une nouvelle colonne. Est-ce possible avec votre méthode?
Voici une autre solution:
cd.cols <- grepl('^cd', colnames(df)) type.cols <- grepl('^type', colnames(df)) flag <- substring(as.matrix(df[,cd.cols]), 1, 3) == '231' & df[,type.cols] == '02' df$flag_var <- 1 * (rowSums(flag) > 0) # > df # ID cd1 type1 cd2 type2 cd3 type3 cd4 type4 flag_var # 1 1 231 02 219 02 1321 02 2314 02 1 # 2 2 222 02 0 # 3 3 123 142 0 # 4 4 145 02 521 02 2313 02 1 # 5 5 231 01 0
Pour l'exemple mis à jour, puisque les colonnes cd
et les colonnes type
sont appariées, les éléments suivants le code devrait fonctionner:
df$flag_var <- 1*(rowSums(substring(as.matrix(df[, 2:ncol(df)]), 1, 3) == '231') > 0) # ID cd1 cd2 cd3 cd4 flag_var # 1 1 231 219 1321 2314 1 # 2 2 222 0 # 3 3 123 142 0 # 4 4 145 521 2313 122 1
Merci beaucoup - cela fonctionne à merveille. J'ai réalisé qu'il y avait une autre faille dans mon ensemble de données, qui est qu'il y a une variable supplémentaire qui complique les choses (voir mon article original qui a été modifié).
Nous pourrions parcourir les colonnes et faire une correspondance partielle avec grepl
, Réduire
la liste
de vecteur
s en un seul vecteur
logique et contraindre les valeurs en données binaires
df <- structure(list(ID = c("1", "2", "3", "4"), cd1 = c("231", "222", "123", "145"), cd2 = c("219", "", "142", "521"), cd3 = c("1321", "", "", "2313"), cd4 = c("2314", "", "", "122")), row.names = c(NA, -4L), class = "data.frame")
df$flag_var <- +(Reduce(`|`, lapply(df[-1], grepl, pattern = '^231')))
C'est définitivement au-delà de mon package CRAN 'icd', et 'dplyr' est un bon outil pour le travail; juste un rappel que «icd» pourrait vous aider avec le prétraitement, la validation de code et les calculs de comorbidité plus compliqués dont vous pourriez avoir besoin.