如何从 R 中的列中提取由 | 分隔的字符串并将它们放入单独的列中?

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

我在 R 中有一个如下所示的数据框:

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

我想将每个剂量分成不同的列,所以它看起来像这样:

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

D7 列之前我都需要它,这是它在我的数据集中出现的最大次数。有什么办法可以在 R 中做到这一点?

一种data.table方法

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>

tidyverse 方法是 tidyr::separate() 函数。

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>

只需使用基础 R 即可

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