下午聪明的人。
我有一个相当大的数据集(> 800k行),作为一个例子,我已经抽出了20行2行的小样本。在开始时,只有“主题”列使用向量填充,所有其他列都设置为FALSE。
这将重新创建当前的数据......
Topics <- c("E11,E31,E313,ECAT" , "E1,E20")
E1 <- c(FALSE, FALSE)
E11 <- c(FALSE, FALSE)
E20 <- c(FALSE, FALSE)
E30 <- c(FALSE, FALSE)
E31 <- c(FALSE, FALSE)
E100 <- c(FALSE, FALSE)
E300 <- c(FALSE, FALSE)
E313 <- c(FALSE, FALSE)
ECAT <- c(FALSE, FALSE)
df <- data.frame(Topics,E1,E11,E20,E30,E31,E100,E300,E313,ECAT)
这将提供类似......
Topics E1 E11 E20 E30 E31 E100 E300 E313 ECAT
E11,E31,E313,ECAT FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
E1,E20 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
我想将相关的行,列设置为TRUE,其中主题向量中的每个项都匹配。所以它应该看起来像......
Topics E1 E11 E20 E30 E31 E100 E300 E313 ECAT
E11,E31,E313,ECAT FALSE TRUE FALSE FALSE TRUE FALSE TRUE FALSE TRUE
E1,E20 TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
到目前为止,我一直没能完成这项工作,但我怀疑它是这样的:
strsplit
names(df)
但是我已经尝试了所有种类,但无法理解逻辑。有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
尝试
df[-1] <- t(vapply(strsplit(as.character(df$Topics), ','),
function(x) names(df)[-1] %in% x, logical(ncol(df)-1)))
df
# Topics E1 E11 E20 E30 E31 E100 E300 E313 ECAT
#1 E11,E31,E313,ECAT FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE
#2 E1,E20 TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
或者
df[-1] <- t(vapply(strsplit(as.character(df$Topics), ","), function(x)
!!table(factor(x, levels=names(df)[-1])), logical(ncol(df)-1)))
答案 1 :(得分:1)
这几乎是您所描述的逻辑的逐步方法:
## make note of the column names
Colnames <- names(df[-1])
## Create an empty FALSE matrix to modify later
Mat <- matrix(FALSE, nrow = nrow(df),
ncol = length(Colnames),
dimnames = list(NULL, Colnames))
## Use strsplit to split the "Topics" column
L <- strsplit(as.character(df[[1]]), ",", fixed = TRUE)
## Figure out which values match with which columns
## I'm using matrix indexing here to set those values to TRUE
Mat[cbind(rep(seq_along(L), vapply(L, length, 1L)),
match(unlist(L), Colnames))] <- TRUE
## Replacement in the original dataset
df[-1] <- Mat
df
# Topics E1 E11 E20 E30 E31 E100 E300 E313 ECAT
# 1 E11,E31,E313,ECAT FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE TRUE
# 2 E1,E20 TRUE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
如果您刚开始使用“主题”列,可以考虑以下几种变体:
mtabulate
> library(qdapTools)
> mtabulate(strsplit(as.character(df$Topics), ",", TRUE))
E1 E11 E20 E31 E313 ECAT
1 0 1 0 1 1 1
2 1 0 1 0 0 0
cSplit_e
library(splitstackshape)
cSplit_e(df[1], "Topics", ",", type = "character", fill = 0)
# Topics Topics_E1 Topics_E11 Topics_E20 Topics_E31 Topics_E313 Topics_ECAT
# 1 E11,E31,E313,ECAT 0 1 0 1 1 1
# 2 E1,E20 1 0 1 0 0 0
两者都需要一些额外的工作来确保包含您期望拥有的所有列(以及将1和0转换为TRUE
和FALSE
)。