【问题标题】:How to remove a row which contain only missing values in R?如何删除仅包含 R 中缺失值的行?
【发布时间】:2012-10-03 14:51:08
【问题描述】:

我有一个包含 11 列和 100000 行(例如)的大型数据集,其中我的值是 1、2、3、4。其中 4 是缺失值。有些行完全丢失了。即所有 11 列中的 4 个。例如

"4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"   "4"

现在我需要的是只删除那些完全丢失的行。简而言之,我想保留缺失值小于 11 的行。我使用了 na.omit,但它不适用于我的情况。

提前致谢。

【问题讨论】:

  • 如何做到这一点可能取决于您未提供的信息。这是数据框还是矩阵?这些值是存储为整数还是字符?尝试使用运行str(head(foo)) 的输出来编辑您的问题,其中foo 是您的数据。

标签: r


【解决方案1】:

也许您最好的选择是利用 R 的习语来处理缺失或 NA 值。一旦您编码了NA 值,您就可以使用complete.cases 轻松实现您的目标。

创建一些带有缺失值(即值为 4)的示例数据:

set.seed(123)
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6)
m[4, ] <- rep(4, 6)

NA替换所有等于4的值:

m[m==4] <- NA
m
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1   NA    2    2    2
[2,]    2    3    3    1    2    3
[3,]    3    2    2    1    2    3
[4,]   NA   NA   NA   NA   NA   NA
[5,]   NA    3    1   NA    2    1

现在您可以使用各种处理NA 值的函数。例如,complete.cases 只会返回,你猜对了,完整的案例:

m[complete.cases(m), ]

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    3    3    1    2    3
[2,]    3    2    2    1    2    3

有关详细信息,请参阅 stats 包中的 ?complete.cases?na.fail

【讨论】:

  • 这不是被问到的。 OP 只想删除完全丢失的行。
【解决方案2】:

我在其他地方找到了这个解决方案,并使用 Andrie 的代码将其粘贴到此处以生成初始数据集。

首先生成数据集:

set.seed(123)
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6)
m[4, ] <- rep(4, 6)
m[m==4] <- NA
m

这是初始数据集:

1    1    NA   2    2    2
2    3    3    1    2    3
3    2    2    1    2    3
NA   NA   NA   NA   NA   NA
NA   3    1    NA   2    1

现在删除仅包含缺失观察的行:

m[rowSums(is.na(m))<ncol(m),] 

结果如下:

1    1    NA   2    2    2
2    3    3    1    2    3
3    2    2    1    2    3
NA   3    1    NA   2    1

【讨论】:

    【解决方案3】:

    真正快速的方法是使用一点数学。假设您的数据框称为 datf

    rsum <- rowSums(datf)
    datf <- datf[rowSums != 44,] #11 * 4
    

    (也适用于矩阵)

    【讨论】:

    • 我不会给你负1,但是这种方法很危险。它适用于这种特定情况,但是如果添加/删除列会发生什么?始终尝试以稳健的方式解决问题。
    • 这行不通,因为一行的总和可以为 44,而所有元素都不为 4(例如c(4,4,4,4,4,4,4,4,4,3,5))。
    • 注意问题...此数据集中的值只能是 1、2、3 或 4。
    • 而且,是的,它并不健壮,但如果作者想要快速,有时你会为速度创建一个非常有针对性的函数......有时你需要权衡健壮性。 (我认为指出它缺乏鲁棒性是件好事......现在为它真的非常快并解决问题而欢呼怎么样?)
    • @John:我同意有时您可能希望以稳健性换取速度,但这不是其中之一,因为您可以两者兼得(请参阅我的回答)。
    【解决方案4】:

    这是我能想到的最快的解决方案。我将使用类似于@Andrie 的示例数据。

    set.seed(21)
    m <- matrix(sample(1:6, 110, replace=TRUE), ncol=11)
    missVal <- 4
    m[4, ] <- rep(missVal, 11)
    m <- m[ rowSums((m==missVal)) != NCOL(m), ]
    

    最后一行有效,因为 m==missVal 返回一个逻辑 (TRUE/FALSE) 值矩阵。 rowSumsTRUE 转换为 1 并将 FALSE 转换为 0,因此在这种情况下,只要 rowSums 返回 11,我们就知道所有列都是 4

    【讨论】:

      【解决方案5】:

      使用data.table 来提高内存效率。创建is.na(x) 的解决方案是创建一个与原始数据集一样大的数据集,因此效率低下。

      library(data.table)
      DT <- as.data.table(m)
      missing_value <- 4
      missing <- as.data.table(setNames(as.list(rep(4, length(DT)), names(DT))
      setkeyv(DT, names(DT))
      setkey(missing, names(DT))
      
      DT[-DT[(missing),which=T]]
      

      这个和@JoshuaUlrich 的解决方案对于大数据来说都是快速的

      set.seed(21)
      m <- matrix(sample(1:6, 1100000, replace=TRUE), ncol=11)
      missVal <- 4
      missing_rows <- sample(100000, 53)
      m[missing_rows, ] <- rep(missVal, 11)
      
      DT <- as.data.table(m)
      setkeyv(DT, names(DT))
      missing <- setNames(as.list(rep(missVal, 11)), names(DT))
      
      system.time({DT1 <- DT[-DT[missing,which=T]]})
      ## user  system elapsed 
      ## 0.02    0.00    0.01 
      system.time({m1 <- m[ rowSums((m==missVal)) != NCOL(m), ]})
      ## user  system elapsed 
      ## 0.02    0.02    0.03 
      

      【讨论】:

      • 小心使用T/F 而不是TRUE/FALSE,因为TF 可以重新定义。
      【解决方案6】:

      这样的事情应该可以解决问题(并且应该适用于矩阵和 data.frames):

      ac<-matrix(c("4","4","4","4","4","4","4","3","3","4","4", rep("4", 11)), nrow=2, ncol=11, byrow=TRUE)
      
      rowsToRemove<-which(apply(ac, 1, function(currow){
          all(currow=="4")
      }))
      

      现在你可以简单地做

      newac<-ac[-rowsToRemove,]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-22
        • 2012-11-07
        • 1970-01-01
        • 2020-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多