您可以使用 splitstackshape 中的 cSplit 将“问题”列用分号 (sep=';') 分隔。指定long 的方向,然后使用dcast.data.table 将其重新整形为wide。然后根据它是否具有NA,将“蓝色”到“粉红色”列中的“值”更改为“是/否”。但是,与Yes/No 相比,将结果作为逻辑索引TRUE/FALSE 总是更好(我们将从!is.na 步骤获得)。
library(splitstackshape)
library(data.table)
res <- dcast.data.table(cSplit(df, 'Issue', sep=';', 'long'),
ID+Title~Issue, value.var='Issue')
nm1 <- names(res)[3:6]
res[,(nm1):=lapply(.SD, function(x)
c("No", "Yes")[(!is.na(x))+1L]), .SDcols=nm1]
res
# ID Title Blue Green Orange Pink
#1: ABC.001.0001 Around and up Yes Yes No No
#2: ABC.001.0002 Over and beyond No Yes Yes No
#3: ABC.001.0003 Inside out No No Yes Yes
或者您可以使用cSplit_e(来自@Ananda Mahto 的 cmets)
cSplit_e(df, "Issue", sep = "; ", type = "character",
fill = 0, drop = TRUE)
或使用base R 的选项。在这里,我使用strsplit 拆分“问题”列,然后使用rbind 列表输出创建“m1”。创建一个唯一值向量(“lvls”)。使用 apply 和 MARGIN 为“1”检查哪些“lvls”在“m1”(lvls %in% x)的每一行中。通过向其添加“1”('x)+1L`)将逻辑向量转换为数字,并将其用作“是/否”值的索引。
df1 <- df[-2]
m1 <- do.call(rbind,strsplit(df$Issue, '; '))
lvls <- unique(c(m1))
df1[lvls] <- t(apply(m1, 1, function(x) c('No', 'Yes')[(lvls
%in% x)+1L]))
df1
# ID Title Green Pink Blue Orange
#1 ABC.001.0001 Around and up Yes No Yes No
#2 ABC.001.0002 Over and beyond Yes No No Yes
#3 ABC.001.0003 Inside out No Yes No Yes
数据
df <- structure(list(ID = c("ABC.001.0001", "ABC.001.0002",
"ABC.001.0003"), Issue = c("Green; Blue", "Green; Orange", "Pink; Orange"),
Title = c("Around and up", "Over and beyond", "Inside out")),
.Names = c("ID", "Issue", "Title"), class = "data.frame",
row.names = c(NA, -3L))