删除colsums = 0的列

时间:2015-07-14 03:19:15

标签: r

我有一个矩阵,其元素是0,1,2,NA!
我想删除其colsums等于0或NA的列!我想从原始矩阵中删除这些列,并为这些列创建一个新矩阵(非零colsums)!  (我认为在计算colsums时我考虑了na.rm = True并删除co​​lsum = 0的colums,因为如果我认为na.rm = False,我的colsums的所有值都得到NA)

这是我的矩阵格式:

mat[1:6,1:6]

1:11059017  1:11088817  1:11090640   1:11099385   1:1109967  1:111144756

 0        0            0             0           NA          0
 0        0            0             0           0          NA
 1       NA            2             0           NA          0    
 0        0            0             1          0           2  
 2        0            0             0          0           0
 0        0            NA            0          0           0

 Summat <-  colSums(mat,na.rm = TRUE)

head(summat)

1:11059017  1:11088817  1:11090640   1:11099385   1:1109967  1:111144756 

[,1]   3           0             2          1           0            2

第2列和第5列的colsum = 0所以我应该从met中删除它们,并将其余列保留在另一个矩阵中。

我的输出应该如下:

met-nonzero

 1:11059017      1:11090640     1:11099385     1:111144756

  0             0                  0                0
  0             0                  0                NA
  1             2                  0                0
  0             0                  1                2  
  2             0                  0                0
  0             NA                 0                0
请问我能告诉我怎么办?

数据:

structure(c(0L, 0L, 1L, 0L, 2L, 0L, 0L, 0L, NA, 0L, 0L, 0L, 0L, 
0L, 2L, 0L, 0L, NA, 0L, 0L, 0L, 1L, 0L, 0L, NA, 0L, NA, 0L, 0L, 
0L, 0L, NA, 0L, 2L, 0L, 0L), .Dim = c(6L, 6L), .Dimnames = list(
    NULL, c("X1.11059017", "X1.11088817", "X1.11090640", "X1.11099385", 
    "X1.1109967", "X1.111144756")))

由于

1 个答案:

答案 0 :(得分:5)

找出哪些人有colSums != 0

i <- (colSums(mat, na.rm=T) != 0) # T if colSum is not 0, F otherwise

然后你可以选择或删除它们,例如

matnonzero <- mat[, i] # all the non-zero columns
matzeros <- mat[, !i]  # all the zero columns

更新评论(有没有colSums的方法)。 IMO,是的,但是,colSums是更优雅/更有效的方式之一。

您可以执行以下操作:

apply(is.na(mat) | mat == 0, 2, all)

对于全NA / 0的每列都将返回TRUE,以便

mat[, !apply(is.na(mat) | mat == 0, 2, all)]

将返回所有非零列。

colSumsapply快。

system.time( replicate(1000, mat[, !apply(is.na(mat) | mat == 0, 2, all)]) )
#   user  system elapsed 
#  0.068   0.000   0.069 
system.time( replicate(1000, mat[, colSums(mat, na.rm=T) != 0]))
#   user  system elapsed 
#  0.012   0.000   0.013 

我确信还有很多其他方法可以做到。

再次更新 ,因为OP会在评论中不断添加问题。 新问题是:删除所有列:

  • 有0或NA
  • 整个列中包含所有相同的值。

机制没有改变 - 你只需要为每一列决定是否保留它的布尔值(true或false)。

e.g。

就像列中的all值为is.na==0一样,您可以删除列,但是您可以编写第二个条件(例如)length(unique({column})) == 1或{ {1}},或许多其他等效方式。

因此要合并它们,请记住all(diff({column})) == 0会将函数apply(X, 2, FUN)应用于FUN的每一列。

所以你可以这样做:

X

如果列具有任何NAs或0,或者整个列只有一个唯一值,则返回i <- apply(mat, 2, function (column) { any(is.na(col) | col == 0) | length(unique(col)) == 1 }) 。如果我们应该丢弃该列,那么这是TRUE。然后像以前一样对矩阵进行子集化,即

TRUE

如果您希望为您已经要求的条件添加更多条件 ,请仔细考虑并亲自尝试,如果您仍然不能,请提出新问题而不是再次修改这个。