Найдите числовые и символьные столбцы, которые идеально коррелируют/избыточны

У меня есть набор данных с несколькими сотнями столбцов. Он содержит данные списка рассылки, и несколько столбцов кажутся точными копиями друг друга, но в другой форме.

Например:

rowNum    StateCode       StateName      StateAbbreviation
  1          01             UTAH               UT
  2          01             UTAH               UT
  3          03             TEXAS              TX
  4          03             TEXAS              TX
  5          03             TEXAS              TX
  6          44             OHIO               OH
  7          44             OHIO               OH
  8          44             OHIO               OH
 ...         ...            ...                ...

Я хотел бы удалить перекрывающиеся данные и просто сохранить числовые столбцы, если это возможно, чтобы только один столбец содержал одинаковую информацию. Таким образом, приведенный выше пример станет следующим:

rowNum    StateCode
      1          01 
      2          01   
      3          03  
      4          03  
      5          03 
      6          44
      7          44
      8          44 
     ...         ...  

Я пытался использовать cor(), но это работает только для числовых переменных. Я пробовал caret::nearZeroVar(), но это работает только в самой колонке.

Есть ли у кого-нибудь предложения по поиску идеально коррелированных столбцов с нечисловыми данными?

Спасибо.


person screechOwl    schedule 04.09.2012    source источник
comment
Просто отредактировал мой ответ, чтобы упростить его подход. Теперь он использует cor(), который я, конечно, должен был взять из вашего вопроса для начала. Спасибо за классный вопрос.   -  person Josh O'Brien    schedule 05.09.2012
comment
@JoshO'Brien: отлично работает. Большое тебе спасибо.   -  person screechOwl    schedule 05.09.2012


Ответы (4)


Вот веселое и быстрое решение. Сначала он преобразует data.frame в правильно структурированную матрицу целочисленного класса, а затем использует cor() для идентификации избыточных столбцов.

## Read in the data
df <- read.table(text="rowNum    StateCode       StateName      StateAbbreviation
  1          01             UTAH               UT
  2          01             UTAH               UT
  3          03             TEXAS              TX
  4          03             TEXAS              TX
  5          03             TEXAS              TX
  6          44             OHIO               OH
  7          44             OHIO               OH
  8          44             OHIO               OH", header=TRUE)

## Convert data.frame to a matrix with a convenient structure
## (have a look at m to see where this is headed)
l <- lapply(df, function(X) as.numeric(factor(X, levels=unique(X))))
m <- as.matrix(data.frame(l))

## Identify pairs of perfectly correlated columns    
M <- (cor(m,m)==1)
M[lower.tri(M, diag=TRUE)] <- FALSE

## Extract the names of the redundant columns
colnames(M)[colSums(M)>0]
[1] "StateName"         "StateAbbreviation"
person Josh O'Brien    schedule 04.09.2012

Будет ли это делать трюк? Я основываюсь на идее, что если вы вызовете table(col1, col2), любые столбцы в таблице будут иметь только одно ненулевое значение, если столбцы дублируются, например:

     OHIO TEXAS UTAH
  1     0     0    2
  3     0     3    0
  44    3     0    0

Что-то вроде этого:

dup.cols <- read.table(text='rowNum    StateCode       StateName      StateAbbreviation
  1          01             UTAH               UT
  2          01             UTAH               UT
  3          03             TEXAS              TX
  4          03             TEXAS              TX
  5          03             TEXAS              TX
  6          44             OHIO               OH
  7          44             OHIO               OH
  8          44             OHIO               OH', header=T)
library(plyr)
combs <- combn(ncol(dup.cols), 2)
adply(combs, 2, function(x) {
  t <- table(dup.cols[ ,x[1]], dup.cols[ , x[2]])
  if (all(aaply(t1, 2, function(x) {sum(x != 0) == 1}))) {
    paste("Column numbers ", x[1], x[2], "are duplicates")
  }
})
person Marius    schedule 04.09.2012

Это должно вернуть вам карту, показывающую, какие переменные соответствуют друг другу.

check.dup <- expand.grid(names(dat),names(dat)) #find all variable pairs
check.dup[check.dup$Var1 != check.dup$Var2,] #take out self-reference
check.dup$id <- mapply(function(x,y) {
        x <- as.character(x); y <- as.character(y)
            #if number of levels is different, discard; keep the number for later
        if ((n <- length(unique(dat[,x]))) != length(unique(dat[,y])))  {
            return(FALSE)
            }
            #subset just the variables in question to get pairs
        d <- dat[,c(x,y)]
            #find unique pairs
        d <- unique(d)
            #if number of unique pairs is the number of levels from before,
            #then the pairings are one-to-one
        if( nrow(d) == n ) {
            return(TRUE)
        } else return(FALSE)
    },
    check.dup$Var1,
    check.dup$Var2
)
person Blue Magister    schedule 04.09.2012

person    schedule
comment
Вопрос касался повторяющихся столбцов, а не строк. - person Marius; 05.09.2012
comment
@Marius: Если вы являетесь источником голосования -1, позвольте мне спросить вас, считаете ли вы разумным понизить ответ после того, как ОП изменил вопрос на что-то другое, чем то, с чего он начинался. ? Когда я опубликовал этот ответ, в нем не было столбца StateAbbreviation, и в вопросе не было примера правильного ответа. Меня не беспокоит общее количество баллов, но я думаю, что голосование против, когда вопросы меняются, - это плохое гражданство. - person IRTFM; 05.09.2012
comment
Я согласен - отрицательный голос здесь не служит никакой полезной цели, а просто делает ТАК менее дружелюбным местом. - person Josh O'Brien; 05.09.2012
comment
Извините, я думал, что это ответ, основанный на беглом прочтении вопроса (найдите дубликаты!). Я не знал, что это было опубликовано до редактирования. - person Marius; 05.09.2012