【问题标题】:Removing empty rows of a data file in R在R中删除数据文件的空行
【发布时间】:2011-09-20 04:45:44
【问题描述】:

我有一个空行的数据集。我想删除它们:

myData<-myData[-which(apply(myData,1,function(x)all(is.na(x)))),]

它工作正常。但现在我想在我的数据中添加一列并初始化第一个值:

myData$newCol[1] <- -999

Error in `$<-.data.frame`(`*tmp*`, "newCol", value = -999) : 
  replacement has 1 rows, data has 0

不幸的是,它不起作用,我真的不明白为什么,我无法解决这个问题。 当我一次删除一行时,它起作用了:

TgData = TgData[2:nrow(TgData),]

或类似的东西。

当我只使用前 13.000 行时它也有效。

但它不适用于我的实际数据,有 32.000 行。

我做错了什么?这对我来说似乎没有意义。

【问题讨论】:

标签: r


【解决方案1】:

使用dplyrif_all/if_any

删除任何 NA 的行或选择没有 NA 值的行。

df %>% filter(!if_any(a:c, is.na))

#  a b c
#1 1 a e
#2 3 c g

#Also
df %>% filter(if_all(a:c, Negate(is.na)))

删除包含所有 NA 值的行或选择包含至少一个非 NA 值的行。

df %>% filter(!if_all(a:c, is.na))

#     a b c
#1    1 a e
#2 <NA> b f
#3    3 c g

#Also
df %>% filter(if_any(a:c, Negate(is.na)))

数据

使用来自@sbha 的数据 -

df <- data.frame(a = c('1', NA, '3', NA), 
                 b = c('a', 'b', 'c', NA), 
                 c = c('e', 'f', 'g', NA))

【讨论】:

    【解决方案2】:

    如果您只想要一个方便的函数包装器,这里还有另一个答案。此外,上述许多解决方案都删除了带有 ANY NA 的行,而这个只删除了所有 NA 的行。

    data <- rbind(c(1,2,3), c(1, NA, 4), c(4,6,7), c(NA, NA, NA), c(4, 8, NA)) # sample data
    data
    
    rmNArows<-function(d){
    goodRows<-apply(d,1,function(x) sum(is.na(x))!=ncol(d))
    d[goodRows,]
    }
    
    rmNArows(data)
    

    【讨论】:

      【解决方案3】:

      这里有一些dplyr 选项:

      # sample data
      df <- data.frame(a = c('1', NA, '3', NA), b = c('a', 'b', 'c', NA), c = c('e', 'f', 'g', NA))
      
      library(dplyr)
      
      # remove rows where all values are NA:
      df %>% filter_all(any_vars(!is.na(.)))
      df %>% filter_all(any_vars(complete.cases(.)))  
      
      
      # remove rows where only some values are NA:
      df %>% filter_all(all_vars(!is.na(.)))
      df %>% filter_all(all_vars(complete.cases(.)))  
      
      # or more succinctly:
      df %>% filter(complete.cases(.))  
      df %>% na.omit
      
      # dplyr and tidyr:
      library(tidyr)
      df %>% drop_na
      

      【讨论】:

      • na.omit() 和 drop_na() 都不返回非 NA 行。
      【解决方案4】:

      使用janitor 包的NAs 行的替代解决方案

      myData %>% remove_empty("rows")
      

      【讨论】:

      • 这是最简单的解决方案,它对我有用——谢谢!
      【解决方案5】:

      这类似于上面的一些答案,但是通过这个,您可以指定是否要删除缺失值百分比大于或等于给定百分比的行(使用参数pct

      drop_rows_all_na <- function(x, pct=1) x[!rowSums(is.na(x)) >= ncol(x)*pct,]
      

      其中x 是一个数据框,pct 是您要删除的NA 填充数据的阈值。

      pct = 1 表示删除具有 100% 值 NA 的行。 pct = .5 表示删除至少有一半值的行 NA

      【讨论】:

      • 如何在df上使用这个FUN?
      【解决方案6】:

      我假设您要删除所有为 NA 的行。然后,您可以执行以下操作:

      data <- rbind(c(1,2,3), c(1, NA, 4), c(4,6,7), c(NA, NA, NA), c(4, 8, NA)) # sample data
      data
           [,1] [,2] [,3]
      [1,]    1    2    3
      [2,]    1   NA    4
      [3,]    4    6    7
      [4,]   NA   NA   NA
      [5,]    4    8   NA
      
      data[rowSums(is.na(data)) != ncol(data),]
           [,1] [,2] [,3]
      [1,]    1    2    3
      [2,]    1   NA    4
      [3,]    4    6    7
      [4,]    4    8   NA
      

      如果要删除至少有一个 NA 的行,只需更改条件:

      data[rowSums(is.na(data)) == 0,]
           [,1] [,2] [,3]
      [1,]    1    2    3
      [2,]    4    6    7
      

      【讨论】:

      • 第二种情况也可以通过:data[complete.cases(data),]处理。
      • @JoshuaUlrich 感谢您的帮助回答!只是为了理解?为什么要在data[complete.cases(data),] 代码末尾添加,
      • @mrquad,这意味着您正在按行进行子集化;见stackoverflow.com/a/17052459/2152245
      【解决方案7】:

      如果你有空行,而不是 NA,你可以这样做:

      data[!apply(data == "", 1, all),]
      

      同时删除(NA 和空):

      data <- data[!apply(is.na(data) | data == "", 1, all),]
      

      【讨论】:

        猜你喜欢
        • 2015-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        • 2011-09-22
        • 2016-10-05
        • 1970-01-01
        相关资源
        最近更新 更多