【问题标题】:Remove the columns with the colsums=0删除 colsums=0 的列
【发布时间】:2015-07-14 03:19:14
【问题描述】:

我有一个矩阵,它的元素是 0, 1,2,NA!
我想删除它们的 colsum 等于 0 或 NA 的列!我想从原始矩阵中删除这些列并为这些列创建一个新矩阵(非零列和)! (我认为在计算 colsum 时,我考虑了 na.rm=True 并删除 colsum=0 的列,因为如果我考虑 na.rm=False,我的 colsum 的所有值都会得到 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")))

谢谢

【问题讨论】:

    标签: r


    【解决方案1】:

    找出哪些有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 不断在 cmets 中添加他们的问题.. 新问题是:删除所有列:

    • 有 0 或 NA
    • 整列都包含相同的值。

    机制没有改变 - 您只需为每列确定是否保留它的布尔值(真或假)。

    例如

    就像如果列中的all 值是is.na==0 一样,您删除该列,您可以使用第二个条件编写(例如)length(unique({column})) == 1all(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
          })
    

    如果列有任何 NA 或 0,或者如果整个列只有一个唯一值,则返回 TRUE。所以这是TRUE,如果我们应该丢弃该列。然后像以前一样对矩阵进行子集化,即

    mat[, !i]
    

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

    【讨论】:

    • 我这里还有一个问题!如果我想删除只有 NA 或 0 或两个值的列,除了上述解决方案之外,还有其他解决方案!另一方面,如何在不计算 colSums 的情况下删除所有元素为 0 或 NA 的列?!
    • 如果你想在你原来的问题已经得到回答后附加额外的问题,你应该首先问它或问另一个问题。还有很多其他方法可以做到这一点(我会用一些更新问题)。
    • @Ati,我已经更新了我的答案,将您的 cmets 考虑在内。如果答案已经回答了您的问题,请接受。
    • 谢谢!有用!我需要第二种解决方案,因为除了删除具有 0 和 NA 值的列之外,我还必须删除包含相同值的列(仅包含 0 或仅包含 1 或仅包含 2)!
    • 出于这个原因,我使用了您的第二个解决方案,并向该 mat[, !apply(is.na(mat) | mat == 0 | mat==1 | mat==2, 2、全部)]
    猜你喜欢
    • 2021-12-29
    • 1970-01-01
    • 2020-12-16
    • 2021-09-26
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多