【问题标题】:Removing both row and column of partial NA value删除部分 NA 值的行和列
【发布时间】:2016-08-20 18:43:51
【问题描述】:

我有以下数据框 (s):

s<-read.table(text = "V1    V2  V3  V4  V5  V6  V7  V8  V9  V10 
  1 0   62  64  44  NA  55  81  66  57  53  
  2 0   0   65  50  NA  56  79  69  52  55  
  3 0   0   0   57  NA  62  84  76  65  59  
  4 0   0   0   0   NA  30  70  61  41  36  
  5 0   0   0   0   NA  NA  NA  NA  NA  NA  
  6 0   0   0   0   0   0   66  63  51  44  
  7 0   0   0   0   0   0   0   80  72  72  
  8 0   0   0   0   0   0   0   0   68  64  
  9 0   0   0   0   0   0   0   0   0   47  
  10    0   0   0   0   0   0   0   0   0   0   ", header = TRUE)

可以看出,在这种情况下,第 5 行和第 5 列仅包含 NA0 值。我想省略它们并保持行和列的顺序。同一模式中可能有更多的列和行,我也想做同样的事情。数据框的大小可能会更改。 最终结果是:

    V1  V2  V3  V4  V6  V7  V8  V9  V10 
1   0   62  64  44  55  81  66  57  53  
2   0   0   65  50  56  79  69  52  55  
3   0   0   0   57  62  84  76  65  59  
4   0   0   0   0   30  70  61  41  36  
6   0   0   0   0   0   66  63  51  44  
7   0   0   0   0   0   0   80  72  72  
8   0   0   0   0   0   0   0   68  64  
9   0   0   0   0   0   0   0   0   47  
10  0   0   0   0   0   0   0   0   0   

有没有办法获取省略的行号和列号(在本例中为 5)?

【问题讨论】:

  • 那么可以证明倾倒行/列的 NA 的最小 nr 是多少。是否所有非 NA 值都必须为 0 才能删除?
  • 可以看出它是一个上三角矩阵。在每种情况下,NA 将用于行:从行号列到最后一列(结束)。对于相同的列号:从第一行到相同的行号(本例中为 5)
  • 这可能很明显,但是:您应该使用矩阵,而不是 data.frame。
  • 我确实使用矩阵。如果您可以在无需转换为数据框的情况下使用矩阵输入显示答案,我会很高兴。
  • 有没有办法得到省略的行和列(本例为5)?

标签: r dataframe row na col


【解决方案1】:

您必须更详细地定义您想要放弃的时间。在这种情况下,它看起来像一侧的矩阵,对角线始终为 0。

不过,总的来说,这是我使用的

s[!rowSums(is.na(s))>1,!colSums(is.na(s))>1]

考虑0

s[!rowSums(is.na(s)|s==0)>9,!colSums(is.na(s)|s==0)>9]

【讨论】:

    【解决方案2】:

    我们可以试试

    v1 <- colSums(is.na(s))
    v2 <- colSums(s==0, na.rm=TRUE)
    j1 <- !(v1>0 & (v1+v2)==nrow(s) & v2 >0)
    
    v3 <- rowSums(is.na(s))
    v4 <- rowSums(s==0, na.rm=TRUE)
    i1 <- !(v3>0 & (v3+v4)==ncol(s) & v3 >0)
    s[i1, j1]
    #   V1 V2 V3 V4 V6 V7 V8 V9 V10
    #1   0 62 64 44 55 81 66 57  53
    #2   0  0 65 50 56 79 69 52  55
    #3   0  0  0 57 62 84 76 65  59
    #4   0  0  0  0 30 70 61 41  36
    #6   0  0  0  0  0 66 63 51  44
    #7   0  0  0  0  0  0 80 72  72
    #8   0  0  0  0  0  0  0 68  64
    #9   0  0  0  0  0  0  0  0  47
    #10  0  0  0  0  0  0  0  0   0
    

    假设如果我们改变 's' 中的一个值

     s$V7[3] <- NA
    

    通过运行上面的代码,输出将是

    #   V1 V2 V3 V4 V6 V7 V8 V9 V10
    #1   0 62 64 44 55 81 66 57  53
    #2   0  0 65 50 56 79 69 52  55
    #3   0  0  0 57 62 NA 76 65  59
    #4   0  0  0  0 30 70 61 41  36
    #6   0  0  0  0  0 66 63 51  44
    #7   0  0  0  0  0  0 80 72  72
    #8   0  0  0  0  0  0  0 68  64
    #9   0  0  0  0  0  0  0  0  47
    #10  0  0  0  0  0  0  0  0   0
    

    注意:OP 的条件是 仅包括 NA 和 0 值。我想省略它们

    【讨论】:

      【解决方案3】:

      我打算建议:

      sclean <- s[rowSums(s == 0|is.na(s)) != ncol(s) | (rowSums(s == 0, na.rm=TRUE) == ncol(s)),
              colSums(s == 0|is.na(s) )!= nrow(s) | colSums(s == 0, na.rm=TRUE) == nrow(s)]
      

      【讨论】:

      • 我认为这是不正确的,因为答案是基于大于 1 的 NA 值。它可能有多个 NA 和非 NA(0 除外)。例如,如果我们使用s$V7[3] &lt;- NA,那么它会省略该列,而我的解决方案会保留它。
      • @Avi 添加了保留 0 列的条件。
      • @akrun,我的解决方案似乎将 v7 保留在您的测试用例中。
      【解决方案4】:

      您可以尝试以下方法:

      myRowSums <- rowSums(is.na(s) | s == 0)
      myColSums <- colSums(is.na(s) | s == 0)
      
      sSmall <- s[which(myRowSums != ncol(s)), which(myColSums != nrow(s))]
      

      它适用于以下数据集,以删除完全由 0 和 NA 组成的所有列和行。

      s <- data.frame(a=c(0, rnorm(5), 0), b=c(0, rnorm(2), NA, NA,1, NA), c=c(rep(c(0,NA), 3), 0))
      

      【讨论】:

      • 试试sSmall &lt;- s[myRowSums != ncol(s), myColSums!= nrow(s)]
      • 谢谢@SerbanTanasa。必须解决几个错别字。
      猜你喜欢
      • 2016-07-10
      • 2016-04-20
      • 2018-10-21
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多