Tengo un marco de datos con una columna llamada Enfermedad y una lista Lista de enfermedades (valores únicos de la columna Enfermedad) como esta

Disease
--------------------------
Diabetes, Blood Pressure
Diabetes
Anemia
No
Blood Pressure,Anemia

Intenté usar la función sapply como se muestra a continuación:

xx<-sapply(my_data$Disease, function(x) is.element(toString(stri_split_fixed(x,","))[[1]],unlist(Disease_List))[[1]]  + 0)

Salida

> xx
  0 1 1 0 0

Está considerando los valores separados por comas como un nuevo valor que no está en la lista y devuelve 0.

Necesito la salida como esta

Diabetes    Blood Pressure    Anemia    
1            1                 0
1            0                 0
0            0                 1
0            0                 0
0            1                 1
r
1
Kitooos 14 sep. 2018 a las 03:24

4 respuestas

La mejor respuesta

Nosotras podemos usar mtabulate

library(qdapTools)
cbind(df, mtabulate(strsplit(df$Disease, ",\\s*")))
#                    Disease Anemia Blood Pressure Diabetes No
#1 Diabetes, Blood Pressure      0              1        1  0
#2                 Diabetes      0              0        1  0
#3                   Anemia      1              0        0  0
#4                       No      0              0        0  1
#5    Blood Pressure,Anemia      1              1        0  0

Datos

df <- structure(list(Disease = c("Diabetes, Blood Pressure", "Diabetes", 
 "Anemia", "No", "Blood Pressure,Anemia")), row.names = c(NA, 
 -5L), class = "data.frame")
0
akrun 14 sep. 2018 a las 04:21
 cbind(my_data,+Vectorize(grepl)(disease_list,my_data['Disease']))
                   Disease Diabetes Blood Pressure Anemia No
1 Diabetes, Blood Pressure        1              1      0  0
2                 Diabetes        1              0      0  0
3                   Anemia        0              0      1  0
4                       No        0              0      0  1
5    Blood Pressure,Anemia        0              1      1  0

También puedes usar +sapply(disease_list,grepl,my_data$Disease)

Dónde

my_data = read.table(col.names = 'Disease',
                     stringsAsFactors = FALSE,
                     strip.white = TRUE
                     sep = '|',
                     text = ' Diabetes, Blood Pressure
                                            Diabetes
                                               Anemia
                                                   No
                                Blood Pressure,Anemia')
 disease_list = unique(trimws(unlist(strsplit(as.character(my_data$Disease),','))))
1
Onyambu 14 sep. 2018 a las 01:15

Una opción tidyverse usando tidyr::separate_rows

library(tidyverse)
df %>%
    rowid_to_column("row") %>%
    separate_rows(Disease, sep = ",\\s*") %>%
    mutate(n = 1) %>%
    spread(Disease, n, fill = 0) %>%
    select(-row)
#  Anemia Blood Pressure Diabetes No
#1      0              1        1  0
#2      0              0        1  0
#3      1              0        0  0
#4      0              0        0  1
#5      1              1        0  0

Data de muestra

df <- read.table(text =
    "Disease
'Diabetes, Blood Pressure'
Diabetes
Anemia
No
'Blood Pressure,Anemia'", header = T)
1
Maurits Evers 14 sep. 2018 a las 01:07

Método de splitstackshape

library(splitstackshape)

cSplit_e(df, "Disease", sep = ",",mode = "binary", type = "character", fill = 0, drop = F)
                   Disease Disease_Anemia Disease_Blood Pressure Disease_Diabetes Disease_No
1 Diabetes, Blood Pressure              0                      1                1          0
2                 Diabetes              0                      0                1          0
3                   Anemia              1                      0                0          0
4                       No              0                      0                0          1
5    Blood Pressure,Anemia              1                      1                0          0
1
YOBEN_S 14 sep. 2018 a las 00:43