[英]R - Setting Value Based on Matching to Column Name
下午聪明的人。
我有一个不错的数据集(> 80万行),并以一个示例为例,我抽取了一个20列乘2行的小样本。 首先,只有“主题”(Topics)列填充有矢量,所有其他列均设置为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)
匹配 但是我尝试了各种尝试,无法理解逻辑。 任何人都可以帮我分解一下吗?
尝试
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)))
这几乎是您逐步描述的逻辑的逐步方法:
## 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
从“qdapTools”
> 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
从我的“splitstackshape”包
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
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.