根据列分隔列表的内容创建二进制分类变量

Create binary categorical variables based on contents of a column delimited list

我的数据框中有一个名为 "Cardiac Comorbidity Types" 的变量,其中包含 NA 或各种心脏合并症类型的列分隔列表。我如何为每种可能的合并症创建一个列,然后用 1/0 填写观察结果,其中 1 = 表示存在合并症,0 = 无合并症。

dput(head(et1$`Cardiac Comorbidity Types`,20))
c("MI,", NA, "CAD, Previous CABG or PTCA, MI, Pacemaker,", "Arrhythmia,", 
"CAD, Previous CABG or PTCA, MI, Arrhythmia,", NA, "CAD, Previous CABG or PTCA, MI,", 
"CAD, Previous CABG or PTCA, CHF, Pacemaker,", "CAD, Previous CABG or PTCA,", 
"CAD, Previous CABG or PTCA, Arrhythmia,", "CAD, Previous CABG or PTCA,", 
"CAD, Previous CABG or PTCA, MI,", "CAD, Previous CABG or PTCA, CHF, Arrhythmia,", 
"CAD, Previous CABG or PTCA, Pacemaker,", "CAD, Previous CABG or PTCA, MI, CHF,", 
"CAD, Previous CABG or PTCA, MI, CHF,", NA, "CAD, Previous CABG or PTCA, PVD, Pacemaker,", 
"PVD,", "CAD, Previous CABG or PTCA,")

此外,如果数据是用分号分隔的,我该怎么做?

我们可以使用 tidyrunnestpivot_wider 的组合。

library(dplyr)
library(tidyr)
library(stringr)
data <- data %>% mutate(ID = 1:nrow(data))

data %>% 
  mutate(Cardiac.Comorbidity.Types = str_split(Cardiac.Comorbidity.Types, ", ?")) %>%
  unnest(Cardiac.Comorbidity.Types) %>%
  filter(Cardiac.Comorbidity.Types != "") %>%
  pivot_wider(id_cols = "ID", names_from = Cardiac.Comorbidity.Types, values_from = Cardiac.Comorbidity.Types) %>%
  right_join(data, by="ID") %>%
  mutate_at(vars(-ID,-Cardiac.Comorbidity.Types), ~ as.integer(!is.na(.x))) %>% select(-ID)
# A tibble: 20 x 8
#      MI   CAD `Previous CABG or PTCA` Pacemaker Arrhythmia   CHF   PVD Cardiac.Comorbidity.Types                   
#   <int> <int>                   <int>     <int>      <int> <int> <int> <fct>                                       
# 1     1     0                       0         0          0     0     0 MI,                                         
# 2     0     0                       0         0          0     0     0 NA                                          
# 3     1     1                       1         1          0     0     0 CAD, Previous CABG or PTCA, MI, Pacemaker,  
# 4     0     0                       0         0          1     0     0 Arrhythmia,                                 
# 5     1     1                       1         0          1     0     0 CAD, Previous CABG or PTCA, MI, Arrhythmia, 
...

数据

data <- c("MI,", NA, "CAD, Previous CABG or PTCA, MI, Pacemaker,", "Arrhythmia,", 
"CAD, Previous CABG or PTCA, MI, Arrhythmia,", NA, "CAD, Previous CABG or PTCA, MI,", 
"CAD, Previous CABG or PTCA, CHF, Pacemaker,", "CAD, Previous CABG or PTCA,", 
"CAD, Previous CABG or PTCA, Arrhythmia,", "CAD, Previous CABG or PTCA,", 
"CAD, Previous CABG or PTCA, MI,", "CAD, Previous CABG or PTCA, CHF, Arrhythmia,", 
"CAD, Previous CABG or PTCA, Pacemaker,", "CAD, Previous CABG or PTCA, MI, CHF,", 
"CAD, Previous CABG or PTCA, MI, CHF,", NA, "CAD, Previous CABG or PTCA, PVD, Pacemaker,", 
"PVD,", "CAD, Previous CABG or PTCA,")
data <- data.frame(Cardiac.Comorbidity.Types = data)

我们可以使用 splitstackshape 中的 cSplit_e 转换为二进制列。

splitstackshape::cSplit_e(et1, "Cardiac.Comorbidity.Types", 
                          type = "character", fill = 0)

cSplit_e 中的默认 sep 参数是 ",",如果您有分号分隔的数据,您可以明确提及。

splitstackshape::cSplit_e(et1, "Cardiac.Comorbidity.Types", sep = ";", 
                          type = "character", fill = 0)