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

时间:2015-03-02 17:20:07

标签: r

下午聪明的人。

我有一个相当大的数据集(> 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)
  • 匹配设置行时,列== TRUE

但是我已经尝试了所有种类,但无法理解逻辑。有人可以帮我解决这个问题吗?

2 个答案:

答案 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

如果您刚开始使用“主题”列,可以考虑以下几种变体:

    来自“qdapTools”的
  1. 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
    
  2. 来自我的“splitstackshape”软件包的
  3. 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
    
  4. 两者都需要一些额外的工作来确保包含您期望拥有的所有列(以及将1和0转换为TRUEFALSE)。