在 R 中删除多列

时间:2021-06-10 08:26:14

标签: r

我有 80k 行和 874 列的数据。其中一些列是空的。我在 for 循环中使用 sum(is.na) 来确定空列的索引。由于第一列不为空,如果 sum(is.na) 等于第一列的行数,则表示该列为空。

for (i in 1:ncol(loans)){
  if (sum(is.na(loans[i])) == nrow(loans[1])){
      print(i)
  }
}

现在我知道空列的索引,我想从数据中删除它们。我想过将这些索引存储在数组中并将它们放入循环中,但我认为它不会起作用,因为带有数据的列将替换空列。我怎样才能放下它们?

4 个答案:

答案 0 :(得分:2)

这行得通吗:

df <- data.frame(col1 = rep(NA, 5),
                 col2 = 1:5,
                 col3 = rep(NA,5),
                 col4 = 6:10)
df
  col1 col2 col3 col4
1   NA    1   NA    6
2   NA    2   NA    7
3   NA    3   NA    8
4   NA    4   NA    9
5   NA    5   NA   10
df[,which(colSums(df, na.rm = TRUE) == 0)] <- NULL
df
  col2 col4
1    1    6
2    2    7
3    3    8
4    4    9
5    5   10

另一种方法:

df[!apply(df, 2, function(x) all(is.na(x)))]
  col2 col4
1    1    6
2    2    7
3    3    8
4    4    9
5    5   10

答案 1 :(得分:2)

您应该尝试为您的问题提供一个玩具数据集。

loans <- data.frame(
  a = c(NA, NA, NA),
  b = c(1,2,3),
  c = c(1,2,3),
  d = c(1,2,3),
  e = c(NA, NA, NA)
)


loans[!sapply(loans, function(col) all(is.na(col)))]

sapply 遍历 loans 的列并应用匿名函数检查所有元素是否为 NA。然后将输出强制转换为向量,在本例中为逻辑向量。

tidyverse 选项:

loans[!purrr::map_lgl(loans, ~all(is.na(.x)))]

答案 2 :(得分:1)

dplyr 解决方案:

df %>%
  select_if(!colSums(., na.rm = TRUE) == 0)

答案 3 :(得分:0)

您可以尝试使用 if elsefor loops 等基本技能解决几乎所有问题,但缺点是速度会较慢。

# evaluate each column, if a column meets your condition, remove it, then next
for (i in 1:length(loans)){
  if (sum(is.na(loans[,i])) == nrow(loans)){
    loans[,i] <- NULL
  }
}