Home > Net >  How to extract strings from column in R that are separated by | and put them into separated columns?
How to extract strings from column in R that are separated by | and put them into separated columns?

Time:04-08

I have a dataframe in R that looks like this:

paciente <- c("Gloria", "Lidia", "Fabia", "Ana", "Kelly", "Sueli", "Lucia")
dose <- c('1: 1ª Dose', '1: 1ª Dose | 2: 1ª Dose', '1: 1ª Dose | 2: 2ª Dose | 3: Reforço | 4: D1 - 1ª Dose', '1: D1 - 1ª Dose | 2: 1ª Dose | 3: 1ª Dose | 4: 1ª Dose | 5: 1ª Dose | 6: 1ª Dose | 7: 1ª Dose', '1: Dose', '1: Dose | 2: DU - Única', '1: R1 - 1º Reforço')

data <- as.data.frame(cbind(paciente, dose))

I want to separate each dose into a different column, so it looks something like this:

paciente           D1                       D2
Gloria        1: 1ª Dose                    NA
Lidia         1: 1ª Dose                  2: 1ª Dose
Fabia         1: 1ª Dose                  2: 2ª Dose
Ana           1: D1 - 1ª Dose             2: 1ª Dose
Kelly         1: Dose                       NA
Sueli         1: Dose                     2: DU - Única
Lucia         1: R1 - 1º Reforço            NA

I need it until column D7, which is the max of times it appears in my dataset. Is there any way I can do this in R?

CodePudding user response:

a data.table approach

library(data.table)
# set data.table format
setDT(data)
# create new columns
data[, paste0("D", 1:length(tstrsplit(data$dose, " | ", fixed = TRUE))) := 
       tstrsplit(dose, " | ", fixed = TRUE)][, dose := NULL, ][]

#    paciente                 D1            D2         D3              D4         D5         D6         D7
# 1:   Gloria         1: 1ª Dose          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>
# 2:    Lidia         1: 1ª Dose    2: 1ª Dose       <NA>            <NA>       <NA>       <NA>       <NA>
# 3:    Fabia         1: 1ª Dose    2: 2ª Dose 3: Reforço 4: D1 - 1ª Dose       <NA>       <NA>       <NA>
# 4:      Ana    1: D1 - 1ª Dose    2: 1ª Dose 3: 1ª Dose      4: 1ª Dose 5: 1ª Dose 6: 1ª Dose 7: 1ª Dose
# 5:    Kelly            1: Dose          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>
# 6:    Sueli            1: Dose 2: DU - Única       <NA>            <NA>       <NA>       <NA>       <NA>
# 7:    Lucia 1: R1 - 1º Reforço          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>

CodePudding user response:

A tidyverse way to do this is the tidyr::separate() function.

library(tidyr)

data %>% separate(dose, sep = " \\| ", into = paste0("D", 1:7))

  paciente                 D1            D2         D3              D4         D5         D6         D7
1   Gloria         1: 1ª Dose          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>
2    Lidia         1: 1ª Dose    2: 1ª Dose       <NA>            <NA>       <NA>       <NA>       <NA>
3    Fabia         1: 1ª Dose    2: 2ª Dose 3: Reforço 4: D1 - 1ª Dose       <NA>       <NA>       <NA>
4      Ana    1: D1 - 1ª Dose    2: 1ª Dose 3: 1ª Dose      4: 1ª Dose 5: 1ª Dose 6: 1ª Dose 7: 1ª Dose
5    Kelly            1: Dose          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>
6    Sueli            1: Dose 2: DU - Única       <NA>            <NA>       <NA>       <NA>       <NA>
7    Lucia 1: R1 - 1º Reforço          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>

CodePudding user response:

Just using base R you could do

cbind(data[1],
      trimws(do.call(rbind, 
              lapply(s <- strsplit(data$dose, '\\|'), 
                     `length<-`, m <- max(lengths(s))))) |> 
  `colnames<-`(paste0('D', seq_len(m))
))

#   paciente                 D1            D2         D3              D4         D5         D6         D7
# 1   Gloria         1: 1ª Dose          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>
# 2    Lidia         1: 1ª Dose    2: 1ª Dose       <NA>            <NA>       <NA>       <NA>       <NA>
# 3    Fabia         1: 1ª Dose    2: 2ª Dose 3: Reforço 4: D1 - 1ª Dose       <NA>       <NA>       <NA>
# 4      Ana    1: D1 - 1ª Dose    2: 1ª Dose 3: 1ª Dose      4: 1ª Dose 5: 1ª Dose 6: 1ª Dose 7: 1ª Dose
# 5    Kelly            1: Dose          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>
# 6    Sueli            1: Dose 2: DU - Única       <NA>            <NA>       <NA>       <NA>       <NA>
# 7    Lucia 1: R1 - 1º Reforço          <NA>       <NA>            <NA>       <NA>       <NA>       <NA>

Data:

data <- structure(list(paciente = c("Gloria", "Lidia", "Fabia", "Ana", 
"Kelly", "Sueli", "Lucia"), dose = c("1: 1ª Dose", "1: 1ª Dose | 2: 1ª Dose", 
"1: 1ª Dose | 2: 2ª Dose | 3: Reforço | 4: D1 - 1ª Dose", 
"1: D1 - 1ª Dose | 2: 1ª Dose | 3: 1ª Dose | 4: 1ª Dose | 5: 1ª Dose | 6: 1ª Dose | 7: 1ª Dose", 
"1: Dose", "1: Dose | 2: DU - Única", "1: R1 - 1º Reforço"
)), class = "data.frame", row.names = c(NA, -7L))
  • Related