首先确保您的数据是字符而不是因素。然后将每一行和每一行拆分为一个 data.frame,获取'/' 上的 str_split,将名称设置为等于值,并将其设为列表。现在您可以将这些结果绑定在一起,最后将所有非 na 值设置为 1。
library(tidyverse) # dplyr, + stringr for str_split, + purrr for map
df %>%
mutate_all(as.character) %>%
split(seq(nrow(.))) %>%
map(~ str_split(., '/') %>% unlist %>% setNames(., .) %>% as.list) %>%
bind_rows %>%
mutate_all(~as.numeric(!is.na(.)))
# # A tibble: 5 x 6
# a ab bb Doa b Dob
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 1 1 1 0 0
# 2 1 0 1 1 1 0
# 3 0 1 0 1 1 1
# 4 1 1 0 1 0 1
# 5 1 0 1 0 1 1
另一个类似的选项(相同的输出)
df %>%
mutate_all(as.character) %>%
split(seq(nrow(.))) %>%
map(~ str_split(., '/') %>% unlist %>% table %>% as.list) %>%
bind_rows %>%
mutate_all(replace_na, 0)
或者您可以先转换为长,然后再转换为宽,类似于 akrun 的回答
library(data.table)
setDT(df)
library(magrittr)
melt(df[, r := 1:.N], 'r') %>%
.[, .(value = strsplit(value, '/')[[1]]), .(r, variable)] %>%
dcast(r ~ value, fun.aggregate = length)
# r Doa Dob a ab b bb
# 1: 1 1 0 1 1 0 1
# 2: 2 1 0 1 0 1 1
# 3: 3 1 1 0 1 1 0
# 4: 4 1 1 1 1 0 0
# 5: 5 0 1 1 0 1 1