如何基于字典将数据框中的ICD-10编码替换为疾病名称
Hey there! Let's work through this ICD-10 code replacement problem together. I get why a simple inner join didn't work for you—your data has multiple diagnosis columns (Dx1, Dx2, Dx3) in wide format, which makes direct joining messy. Here are two practical solutions using tidyverse tools that'll get you to your desired output:
Method 1: Direct Replacement with dplyr::across() and case_match()
This is great if you only have a handful of diagnosis columns, or want a quick, explicit fix. We'll use across() to target all Dx columns, and case_match() to map codes to disease names. We'll also add a fallback to keep the original code if it's not in the dictionary (matching your sample goal where the last Dx3 entry stays "I20"—though note your dictionary does include this code, so that might be a typo in your goal data).
library(dplyr) # First, create a named vector for mapping: code -> disease name code_map <- setNames(CodeDictionary$Disease, CodeDictionary$ICD) # Update all Dx columns in one go df_updated <- df %>% mutate( across( starts_with("Dx"), # Target all columns starting with "Dx" ~case_match( .x, !!!code_map, # Unquote the named vector for matching .default = .x # Keep original code if no match is found ) ) ) # Check the result df_updated
Method 2: Wide-to-Long-to-Wide (Best for Scaling)
If you end up with dozens of diagnosis columns or a huge code dictionary, this method is far more scalable. We'll reshape your data to long format, join with the code dictionary, then reshape back to wide format.
library(dplyr) library(tidyr) df_updated_scalable <- df %>% # Reshape wide to long: each row is one diagnosis code pivot_longer( cols = starts_with("Dx"), names_to = "diagnosis_column", values_to = "icd_code" ) %>% # Join with the code dictionary (left join keeps all rows, even missing codes) left_join(CodeDictionary, by = c("icd_code" = "ICD")) %>% # Use disease name if available, else keep original code mutate(disease_name = ifelse(is.na(Disease), icd_code, Disease)) %>% # Drop unused columns and reshape back to wide format select(id, diagnosis_column, disease_name) %>% pivot_wider( names_from = "diagnosis_column", values_from = "disease_name" ) # Check the result df_updated_scalable
Why Your Original Inner Join Failed
A standard inner join tries to match rows based on a single key column. Since your data has multiple code columns per row, joining directly would either duplicate rows (one per matching code) or drop rows where not all codes are in the dictionary. The methods above work around this by either targeting each column explicitly or normalizing the data structure first.
内容的提问来源于stack exchange,提问作者Dite Bayu

