如何从 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))
我在 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))