繁体   English   中英

R-基于匹配列名称的设置值

[英]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)匹配
  • 匹配设置的行时,列== TRUE

但是我尝试了各种尝试,无法理解逻辑。 任何人都可以帮我分解一下吗?

尝试

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

如果您只是从“主题”列开始,则可以考虑以下几种变化:

  1. 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 
  2. 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转换为TRUEFALSE )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM