R语言 如何按列名删除NA和空值?

0lvr5msh  于 2022-12-20  发布在  其他
关注(0)|答案(5)|浏览(246)

我有以下数据框:

a <- c(3, 2, 1)
a_1 <- c(NA, "", NA)
b <- c(3, 4, 1)
b_1 <- c(3, NA, 4)
c <- c("", "", "")
c_1 <- c(5, 8, 9)
d <- c(6, 9, 10)
d_1 <- c("", "", "")
e <- c(NA, NA, NA)
e_1 <- c(NA, NA, NA)

df <- data.frame(a, a_1, b, b_1, c, c_1, 
                 d, d_1, e, e_1)

我想删除包含"_1"且只有空单元格和NA的列。但是,我只能找到删除数据框中包含空单元格和NA的所有列的代码。

empty_columns <- colSums(is.na(df) | 
        df == "") == nrow(df)
df[, !empty_columns]
df <- df[, colSums(is.na(df)) < nrow(df)]

  a b b_1 c_1  d
1 3 3   3   5  6
2 2 4  NA   8  9
3 1 1   4   9 10

但我希望生成的数据框如下所示:

df2 <- data.frame(a, b, b_1, c, c_1, d, e)

  a b b_1 c c_1  d  e
1 3 3   3     5  6 NA
2 2 4  NA     8  9 NA
3 1 1   4     9 10 NA
gzszwxb4

gzszwxb41#

您可以重新定义empty_columns以检查列名是否包含"_1" ...

empty_columns <- colSums(is.na(df) | df == "") == nrow(df) & grepl("_1", names(df))
2cmtqfgy

2cmtqfgy2#

这里有一个tidyverseselect选项,ends_with("_1")和(&)列具有所有的NA值(在将空白("")转换为NA后,使用na_if,然后删除那些使用-的列

library(dplyr)
df %>%
    select(-(ends_with("_1") & where(~ all(is.na(na_if(as.character(.x), ""))))))
  • 输出
a b b_1 c c_1  d  e
1 3 3   3     5  6 NA
2 2 4  NA     8  9 NA
3 1 1   4     9 10 NA
bis0qfac

bis0qfac3#

首先进行一些清洁和type.convert列。

df[1:10] <- type.convert(df[1:10], as.is=TRUE)

那就是

df[!(colSums(is.na(df)) == nrow(df) & grepl('_1', names(df)))]
#   a b b_1  c c_1  d  e
# 1 3 3   3 NA   5  6 NA
# 2 2 4  NA NA   8  9 NA
# 3 1 1   4 NA   9 10 NA
oewdyzsn

oewdyzsn4#

除了对""NA进行条件测试外,还使用grepl过滤colnames

df[, !(sapply(df, function(x) 
  (any(x == "", na.rm=T) & any(is.na(x))) | 
     all(x == "", na.rm=T) & !all(is.na(x))) & grepl("_1$", colnames(df)))]
  a b b_1 c c_1  d  e e_1
1 3 3   3     5  6 NA  NA
2 2 4  NA     8  9 NA  NA
3 1 1   4     9 10 NA  NA

如果有一列包含空单元格和字母数字值,则此操作也有效。

0x6upsns

0x6upsns5#

如果你像我一样喜欢在列上迭代,那么在empty_columns向量上还有几个即兴重复。OP中棘手的事情是访问每列的名称和值;你可以通过处理名字并检索它们的列来实现,或者使用purrr::imap_lgl,这是一个快捷方式。

empty1 <- sapply(names(df), function(n) all(is.na(df[n]) | df[n] == "") & grepl("_1", n))
empty2 <- purrr::imap_lgl(df, function(col, id) all(is.na(col) | col == "") & grepl("_1", id))

您也可以使用regex来代替组合is.na== ""

empty3 <- purrr::imap_lgl(df, function(col, id) !any(grepl(".", col)) & grepl("_1", id))

所有3个都得到相同的要删除的列集。

df[!empty1]
#>   a b b_1 c c_1  d  e
#> 1 3 3   3     5  6 NA
#> 2 2 4  NA     8  9 NA
#> 3 1 1   4     9 10 NA

相关问题