Удалить все столбцы с 0 из матрицы - PullRequest
12 голосов
/ 09 июля 2011

У меня есть матрица с 15000 столбцами. Некоторые ячейки имеют значения float, а многие имеют 0. Я хочу полностью удалить все столбцы, где все значения 0.

     col1     col2     col3     col4
row1  1        0        0        1
row2  3.4      0        0        2.4
row3  0.56     0        0        0
row4  0        0        0        0

Я хочу удалить столбцы col2 и col3 и оставить остальные. Как я могу сделать это с R? Спасибо

Ответы [ 3 ]

22 голосов
/ 09 июля 2011

Более быстрый способ сделать то же самое (в 3 - 5 раз быстрее) будет

M[,colSums(M^2) !=0]

РЕДАКТИРОВАТЬ: Добавлены детали синхронизации различных подходов, предложенных здесь. Подход, предложенный @Dwin с использованием M[, colSums(abs(M)) ! == 0], кажется наиболее быстрым, особенно когда матрица велика. Я обновлю отчет о сравнительном анализе, если будут предложены другие решения.

m <- cbind(rnorm(1000),0)
M <- matrix(rep(m,7500), ncol=15000)

f_joran   = function(M) M[, !apply(M==0,2,all)]
f_ramnath = function(M) M[, colSums(M^2) != 0]
f_ben     = function(M) M[, colSums(M==0) != ncol(M)]
f_dwin    = function(M) M[, colSums(abs(M)) != 0]

library(rbenchmark)
benchmark(f_joran(M), f_ramnath(M), f_ben(M), f_dwin(M), 
   columns = c('test', 'elapsed', 'relative'), 
   order = 'relative', replications = 10)


          test elapsed relative
4    f_dwin(M)  11.699 1.000000
2 f_ramnath(M)  12.056 1.030515
1   f_joran(M)  26.453 2.261133
3     f_ben(M)  28.981 2.477220
13 голосов
/ 09 июля 2011

Как насчет этого, используя apply и all:

M <- as.matrix(data.frame(a=runif(10),b=rep(0,10),c=runif(10),d=rep(0,10)))

M[,which(!apply(M,2,FUN = function(x){all(x == 0)}))]
3 голосов
/ 09 июля 2011

Вы упоминаете 15000 столбцов, но не количество строк. Если есть несколько тысяч строк и скорость имеет значение, colSums будет немного быстрее, чем apply.

m <- cbind(rnorm(1000),0)
M <- matrix(rep(m,7500), ncol=15000)
system.time(foo <- M[,which(!apply(M==0,2,all))])
#   user  system elapsed 
#   1.63    0.23    1.86 
system.time(bar <- M[,colSums(M)!=0])
#   user  system elapsed 
#  0.340   0.060   0.413
identical(foo,bar)
# [1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...