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))