删除colsums = 0的列

Ati*_*Ati -1 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
Run Code Online (Sandbox Code Playgroud)

第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
Run Code Online (Sandbox Code Playgroud)

你能让我知道我该怎么办?

数据:

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")))
Run Code Online (Sandbox Code Playgroud)

谢谢

mat*_*fee 6

弄清楚哪些有colSums != 0:

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

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

matnonzero <- mat[, i] # all the non-zero columns
matzeros <- mat[, !i]  # all the zero columns
Run Code Online (Sandbox Code Playgroud)

更新评论(没有方法可以做到这一点colSums).IMO,是的,但是,colSums是更优雅/更有效的方式之一.

你可以这样做:

apply(is.na(mat) | mat == 0, 2, all)
Run Code Online (Sandbox Code Playgroud)

对于全NA/0的每列,它将返回TRUE,这样

mat[, !apply(is.na(mat) | mat == 0, 2, all)]
Run Code Online (Sandbox Code Playgroud)

将返回所有非零列.

然而colSums比快apply.

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 
Run Code Online (Sandbox Code Playgroud)

我确信还有很多其他方法可以做到这一点.


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

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

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

例如

就像如果all在一列中的值is.na或者==0您删除列,与你的第二个条件,你可以写(EG) length(unique({column})) == 1,或all(diff({column})) == 0,或许多其他等效方法.

所以要结合它们,请记住apply(X, 2, FUN)将函数FUN应用于每一列X.

所以你可以这样做:

i <- apply(mat,
      2,
      function (column) {
          any(is.na(col) | col == 0) |
          length(unique(col)) == 1
      })
Run Code Online (Sandbox Code Playgroud)

它返回TRUE如果列具有任何NAS或0,或如果整个列仅具有一个唯一的值.所以这就是TRUE我们应该丢弃该列.然后像以前一样对矩阵进行子集化,即

mat[, !i]
Run Code Online (Sandbox Code Playgroud)

如果您希望添加与您已经要求的条件不同的其他条件,请仔细考虑并自己尝试,如果您仍然不能,请提出一个新问题,而不是再次修改此问题.