2015-03-02 2 views
1

Послеобеденные умные люди.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

НО Я пробовал все виды и не могу понять логику. Может ли кто-нибудь сломать это для меня, пожалуйста?

+1

В ожидаемом результате 'E313' должен быть' TRUE' вместо 'E300' – akrun

ответ

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))) 
+0

Epic. Поэтому я целую неделю провожу и, возможно, откладываю 50-60 строк кода, пытаясь заставить это работать. Вы делаете это в ОДНОМ! Выдающийся и просто показывает, как много дальше я должен идти с Р. Уэром. – BarneyC

+0

@BarneyC Рад помочь вам. Он основан только на опыте. – akrun

+0

Могу ли я спросить, что бы я изменил, если бы перед «Тема» был другой столбец? Наверное, я спрашиваю, что означает каждый из индексов -1 и что бы я их установил. Cheers – BarneyC

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 
    

Оба потребует немного дополнительной убедитесь, что все столбцы, которые вы ожидаете, будут включены (d для преобразования от 1 и 0 до TRUE и FALSE).

+0

Это пошаговое руководство является большим и гораздо более соответствует тому, как я думал, что к нему можно подойти. Спасибо за это. – BarneyC

Смежные вопросы