Как уменьшить матрицу без потери имен атрибутов в R

Моя проблема заключается в следующем:

Мне нужно уменьшить матрицу, отрезав несколько столбцов, но сохранив имена векторов-столбцов. DTM — это моя исходная матрица, которая выглядит следующим образом:

>DTM
   word1    word2    word3    word4
[1] 1         1        0        0
[2] 2         0        1        1
[3] 0         1        0        2

и я хочу получить новую матрицу (DTMr в следующем фрагменте кода), которая имеет «метки» и исключает все столбцы, сумма элементов которых меньше порогового значения (скажем, 2):

   word1    word4
[1] 1         0
[2] 2         1
[3] 0         2

>DTMr <- matrix(,nrow=nrow(DTM),ncol=d) # This should be the reduced matrix

где d — количество столбцов DTM, превышающих пороговое значение.

>c = 1 # new counter
>for (col in 1:ncol(DTM))
>{
>  if (sum(DTM[,col]) > 2) 
>  { 
>    DTMr[,c] = DTM[,col]
>    
>    c=c+1
>  }
>}

К сожалению, в этом отношении DTMr совершенен, но теряет все метки (слово 1, ...слово n).

Любые идеи?

Клаудио


person Claudio Meo    schedule 25.05.2012    source источник
comment
на самом деле, DTMr ничего не теряет: у него никогда не было ярлыков...   -  person cbeleites unhappy with SX    schedule 25.05.2012


Ответы (3)


Простое решение с использованием подмножества и colSums:

Создайте некоторые образцы данных:

set.seed(1)
x <- matrix(sample(0:2, 12, replace=TRUE), ncol=4)
colnames(x) <- LETTERS[1:4]
x
     A B C D
[1,] 0 2 2 0
[2,] 1 0 1 0
[3,] 1 2 1 0

Подмножество:

x[, colSums(x)<4]
     A D
[1,] 0 0
[2,] 1 0
[3,] 1 0
person Andrie    schedule 25.05.2012
comment
это был самый краткий, прекрасный ответ - person Claudio Meo; 25.05.2012

Просто используйте apply и простую индексацию:

DTM[,apply(DTM,2,sum) > 2]
     word1 word4
[1,]     1     0
[2,]     2     1
[3,]     0     2

Немного распаковав это, apply(DTM,2,sum) вернет вектор сумм столбцов. Последующее логическое сравнение приводит к логическому вектору, который является ИСТИННЫМ, когда сумма соответствующего столбца больше 2. Наконец, поместив все это во второй аргумент [, выберите только эти столбцы.

И как Бен упоминает в комментариях, colSums — это более быстрый (для больших матриц) и более компактный способ сделать это:

DTM[,colSums(DTM) > 2]
person joran    schedule 25.05.2012
comment
да. colSums() будет быстрее и компактнее, чем apply(DTM,2,sum) - person Ben Bolker; 25.05.2012

Атрибуты сохраняются, если вы удаляете столбцы вместо копирования в новую матрицу без атрибутов

(Я просто использую другую матрицу, которая у меня есть)

> m <- structure(c(26, 5, 21, 2, 2, 1, 0, 1, 1), 
                 .Dim = c(3L, 3L), 
                 .Dimnames = list(c("setosa", "versicolor", "virginica"), 
                                  c("PC1", "PC2", "PC3")))
> m
           PC1 PC2 PC3
setosa      26   2   0
versicolor   5   2   1
virginica   21   1   1

> colSums (m)
PC1 PC2 PC3 
52   5   2 

> m [, colSums (m) <= 2, drop = FALSE]
           PC3
setosa       0
versicolor   1
virginica    1
person cbeleites unhappy with SX    schedule 25.05.2012