【问题标题】:Delete columns/rows with more than x% missing删除缺失超过 x% 的列/行
【发布时间】:2015-10-29 03:40:03
【问题描述】:

我想删除数据框中超过 50% NAs 的所有列或行。

这是我的解决方案:

# delete columns with more than 50% missings
miss <- c()
for(i in 1:ncol(data)) {
  if(length(which(is.na(data[,i]))) > 0.5*nrow(data)) miss <- append(miss,i) 
}
data2 <- data[,-miss]


# delete rows with more than 50% percent missing
miss2 <- c()
for(i in 1:nrow(data)) {
  if(length(which(is.na(data[i,]))) > 0.5*ncol(data)) miss2 <- append(miss2,i) 
}
data <- data[-miss,]

但我正在寻找更好/更快的解决方案。

我也很感激dplyr 解决方案

【问题讨论】:

  • @Ricky 我添加了我的行解决方案,这几乎是一样的
  • 确认我对附加行解决方案的理解:因此,如果行 X 最初具有超过 50% 的 NA,但在删除第 3 列后,比列 X 的 NA 小于 50%,行 X 不应该被删除?

标签: r dplyr


【解决方案1】:

dplyr 解决方案

对于基于逻辑条件的selecting 列,我们可以使用选择助手where(),如:

library(dplyr)

threshold<-0.5 #for a 50% cut-off

df %>% select(where(~mean(is.na(.))< threshold))

对于filtering 行,dplyrs if_any()if_all() 将处理 100 或 0% 截止的情况,如 df %&gt;% filter(if_any(everything(), ~is.na(.x)))。 对于其他阈值的解决方案,可以使用rowMeans

library(dplyr)

df %>% filter(rowMeans(is.na(.)) < threshold)

【讨论】:

    【解决方案2】:

    这里是另一个提示 ro filter df,它的列中有 50 个 NaN:

    ## Remove columns with more than 50% NA
    rawdf.prep1 = rawdf[, sapply(rawdf, function(x) sum(is.na(x)))/nrow(rawdf)*100 <= 50]
    

    这将导致 df 在不大于 50% 的列中只有 NaN。

    【讨论】:

      【解决方案3】:

      要删除具有一定数量 NA 的列,您可以使用 colMeans(is.na(...))

      ## Some sample data
      set.seed(0)
      dat <- matrix(1:100, 10, 10)
      dat[sample(1:100, 50)] <- NA
      dat <- data.frame(dat)
      
      ## Remove columns with more than 50% NA
      dat[, which(colMeans(!is.na(dat)) > 0.5)]
      
      ## Remove rows with more than 50% NA
      dat[which(rowMeans(!is.na(dat)) > 0.5), ]
      
      ## Remove columns and rows with more than 50% NA
      dat[which(rowMeans(!is.na(dat)) > 0.5), which(colMeans(!is.na(dat)) > 0.5)]
      

      【讨论】:

      • 所以行是dat[-which(rowMeans(is.na(dat)) &gt; 0.5), ]。谢谢!
      • @spore234 HTH @PierreLafortune 经过快速测试后,它的速度似乎是等效 sapply 解决方案的 3 倍
      【解决方案4】:

      一个tidyverse 解决方案,在此处删除x% 为NAs(50%) 的列:

      test_data <- data.frame(A=c(rep(NA,12),
                                  520,233,522),
                              B = c(rep(10,12),
                                    520,233,522))
      # Remove all with %NA >= 50
      # can just use >50
      
      
       test_data %>% 
        purrr::discard(~sum(is.na(.x))/length(.x)* 100 >=50)
      

      结果:

           B
      1   10
      2   10
      3   10
      4   10
      5   10
      6   10
      7   10
      8   10
      9   10
      10  10
      11  10
      12  10
      13 520
      14 233
      15 522
      

      【讨论】:

      • 是否可以使用此方法删除分组 data.frame 中某一列缺失值超过 50% 的任何组?
      • 没有实际数据,很难测试,但您可以执行以下操作:df %&gt;% group_by(grouping_col) %&gt;% filter(!mean(is.na(target_column)) &gt;= 0.5)。您要根据分组删除所有列还是删除单个列?后者可能不太明显。
      猜你喜欢
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 2022-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多