Je suis nouveau dans R et j'essaie actuellement de sous-regrouper mes données en fonction de mes critères d'exclusion prédéfinis pour l'analyse. J'essaie actuellement de supprimer tous les cas de démence, comme codé par la CIM-10. Le problème est qu'il existe plusieurs variables contenant des informations sur l'état de santé de chaque individu (~ 70 variables), même si comme elles sont codées de la même manière, la même condition peut être appliquée à toutes.
Quelques données simulées:
ID disease_code_1 disease_code_2 disease_code_3 1 1001 I802 A071 H250 2 1002 H356 NA NA 4 1004 D235 NA I802 5 1005 B178 NA NA 8 1008 C761 NA NA 11 1011 J679 A045 D352
Ici, j'essaie de supprimer tous les cas qui ont un "code de démence" dans l'une des variables "code_maladie". p>
Error in 2:4 != "F023" | "G20" : operations are possible only for numeric, logical or complex types
L'erreur que je reçois est:
#Remove cases with dementia from dataframe (e.g. F023, G20) Newdata_df <- subset(df, (2:4 != "F023"|"G20"|"F009"|"F002"|"F001"|"F000"|"F00"| "G309"| "G308"|"G301"|"G300"|"G30"| "F01"|"F018"|"F013"| "F012"| "F011"| "F010"|"F01"))
Idéalement, le dataframe sous-défini ressemblerait à ceci:
XXX
Je sais qu'il y a une erreur dans mon code même si je ne sais pas exactement comment la corriger. J'ai essayé plusieurs autres méthodes (en utilisant dplyr) mais je n'ai pas eu de chance jusqu'à présent.
Toute aide est grandement appréciée!
6 Réponses :
Que diriez-vous de ceci:
> df[apply(df[-1], 1, function(x) {!any(x %in% dementia)}),] ID disease_code_1 disease_code_2 disease_code_3 1 1001 I802 A071 H250 2 1002 H356 NA NA 4 1004 D235 NA I802 5 1005 B178 NA NA 8 1008 C761 NA NA 11 1011 J679 A045 D352
Modifier:
Une solution encore plus élégante, grâce à @ Ronan Shah:
> dementia <- c("F023", "G20", "F009", "F002", "F001", "F000", "F00", "G309", "G308", + "G301", "G300", "G30", "F01", "F018", "F013", "F012", "F011", "F010", "F01") > > dementia <- apply(sapply(df[, -1], function(x) {x %in% dementia}), 1, any) > > df[!dementia,] ID disease_code_1 disease_code_2 disease_code_3 1 1001 I802 A071 H250 2 1002 H356 NA NA 4 1004 D235 NA I802 5 1005 B178 NA NA 8 1008 C761 NA NA 11 1011 J679 A045 D352 >
J'espère que cela vous aidera.
@ Ronan Shah Nice! C'est une solution plus élégante. Vous devriez le poster.
Nous pouvons créer un vecteur avec les codes à supprimer et utiliser rowSums
pour supprimer, c'est-à-dire
ID disease_code_1 disease_code_2 disease_code_3 1 1001 I802 A071 H250 2 1002 H356 NA NA 4 1004 D235 NA I802 5 1005 B178 NA NA 8 1008 C761 NA NA 11 1011 J679 A045 D352
ce qui donne,
codes_to_remove <- c("F023", "G20", "F009", "F002", "F001", "F000", "F00", "G309", "G308", "G301", "G300", "G30", "F01", "F018", "F013", "F012", "F011", "F010", "F01") df[rowSums(sapply(df[-1], `%in%`, codes_to_remove)) == 0,]
Une possibilité dplyr
pourrait être:
df %>% filter_at(vars(contains("disease_code")), all_vars(! . %in% c("F023","G20","F009","F002","F001","F000","F00", "G309", "G308","G301","G300","G30", "F01","F018","F013", "F012", "F011", "F010","F01")))
Dans ce cas, il vérifie si l'une des colonnes 2: 4 contient l'un des codes donnés. p>
Ou:
df %>% filter_at(vars(2:4), all_vars(! . %in% c("F023","G20","F009","F002","F001","F000","F00", "G309", "G308","G301","G300","G30", "F01","F018","F013", "F012", "F011", "F010","F01"))) ID disease_code_1 disease_code_2 disease_code_3 1 1001 I802 A071 H250 2 1002 H356 NA NA 3 1004 D235 NA I802 4 1005 B178 NA NA 5 1008 C761 NA NA 6 1011 J679 A045 D352
Dans ce cas, il vérifie si l'une des colonnes portant le nom maladie_code
contient l'un des codes donnés.
Merci à tous pour vos suggestions! J'apprécie que vous ayez également expliqué ce que votre code suggéré fait @tmfmnk - vraiment utile!
Comme mentionné dans les commentaires de @docendo discimus, nous pouvons convertir la trame de données au format long en utilisant rassembler
, group_by
ID
et sélectionner uniquement ceux ID s qui ne contiennent pas de dementia_code
, puis répartissez
ces derniers vers un format large.
dementia_code <- c("F023", "G20", "F009", "F002", "F001", "F000", "F00", "G309", "G308","G301", "G300", "G30", "F01", "F018", "F013", "F012", "F011", "F010", "F01")
library(tidyverse) df %>% gather(key, value, -ID) %>% group_by(ID) %>% filter(!any(value %in% dementia_code)) %>% spread(key, value) # ID disease_code_1 disease_code_2 disease_code_3 # <dbl> <chr> <chr> <chr> #1 1001 I802 A071 H250 #2 1002 H356 NA NA #3 1004 D235 NA I802 #4 1005 B178 NA NA #5 1008 C761 NA NA #6 1011 J679 A045 D352
Pourquoi charger tout tidyverse
? N'est-ce pas simplement tidyr
et dplyr
?
@Dunois oui, ça l'est. J'ai l'habitude de tout charger par défaut: P
Nous pourrions également le faire en utilisant un anti_join
tel que Newdata_df <- df%>% anti_join (df%>% rassembl (DiseaseCodeNumber, CodeValue, -ID)%>% filter (CodeValue% in % c ("F023", "G20", "F009", "F002", "F001", "F000", "F00", "G309", "G308", "G301", "G300", "G30" , "F01", "F018", "F013", "F012", "F011", "F010", "F01")), par = "ID")
Une version de boucle pour
avec base
R, au cas où vous préférez.
df <- data.frame(ID = c(1001, 1002, 1003, 1004, 1005,1006,1007,1008,1009,1010,1011), disease_code_1 = c('I802','H356','G560','D235','B178','F011','F023','C761','H653','A049','J679'), disease_code_2 = c('A071','NA','G20','NA','NA','A049','NA','NA','G300','G308','A045'), disease_code_3 = c('H250','NA','NA','I802','NA','A481','NA','NA','NA','NA','D352'), stringsAsFactors = FALSE) dementia_codes <- c("F023", "G20", "F009", "F002", "F001", "F000", "F00", "G309", "G308", "G301", "G300", "G30", "F01", "F018", "F013", "F012", "F011", "F010", "F01") new_df <- df[0,] for(i in 1:nrow(df)){ currRow <- df[i,] if(any(dementia_codes %in% as.character(currRow)) == FALSE){ new_df <- rbind(new_df, currRow) } } new_df # ID disease_code_1 disease_code_2 disease_code_3 # 1 1001 I802 A071 H250 # 2 1002 H356 NA NA # 4 1004 D235 NA I802 # 5 1005 B178 NA NA # 8 1008 C761 NA NA # 11 1011 J679 A045 D352
Nous pouvons utiliser melt / dcast
de data.table
dementia_codes <- c("F023", "G20", "F009", "F002", "F001", "F000", "F00", "G309", "G308", "G301", "G300", "G30", "F01", "F018", "F013", "F012", "F011", "F010", "F01")
Ou cela peut être fait de manière plus compacte dans base R sans remodelage
df[!Reduce(`|`, lapply(df[-1], `%in%` , dementia_codes)),] # ID disease_code_1 disease_code_2 disease_code_3 #1 1001 I802 A071 H250 #2 1002 H356 NA NA #4 1004 D235 NA I802 #5 1005 B178 NA NA #8 1008 C761 NA NA #11 1011 J679 A045 D352
library(data.table) dcast(melt(setDT(df), id.var = 'ID')[, if(!any(value %in% dementia_codes)) .SD, .(ID)], ID ~ variable) # ID disease_code_1 disease_code_2 disease_code_3 #1: 1001 I802 A071 H250 #2: 1002 H356 NA NA #3: 1004 D235 NA I802 #4: 1005 B178 NA NA #5: 1008 C761 NA NA #6: 1011 J679 A045 D352
Vous devez remodeler vos données au format long. Cela vous facilitera la vie (et l'analyse).
Et gardez le package CRAN icd à l'esprit pour conserver votre santé mentale . De nombreux problèmes similaires à celui-ci bénéficient ou nécessitent l'application de cartes de comorbidité, ce que
icd
fait très soigneusement et rapidement en utilisant des cartes de maladies bien validées et largement citées. Cela ne répond pas à votre question, mais l'utilisation de cette technique aurait pu éviter ce problème, en fonction de ce que vous aviez déjà fait et de ce que vous alliez faire avec les données.