使用dplyr管道删除空列

DTY*_*TYK 2 r dplyr

我有一个广泛格式的参与者问卷答复数据框,每列代表一个特定的问题/项目.

数据框看起来像这样:

id <- c(1, 2, 3, 4)
Q1 <- c(NA, NA, NA, NA)
Q2 <- c(1, "", 4, 5)
Q3 <- c(NA, 2, 3, 4)
Q4 <- c("", "", 2, 2)
Q5 <- c("", "", "", "")
df <- data.frame(id, Q1, Q2, Q3, Q4, Q5)
Run Code Online (Sandbox Code Playgroud)

我希望R删除在每个行中具有所有值的列,这些行是(1)NA或(2)空白.因此,我不希望列Q1(完全由NAs组成)和列Q5(完全由""形式的空白组成).

根据这个帖子,我可以使用以下内容删除完全由NA组成的列:

df[, !apply(is.na(df), 2, all]
Run Code Online (Sandbox Code Playgroud)

但是,该解决方案不解决空白("").当我在dplyr管道中完成所有这些操作时,是否还有人可以解释如何将上述代码合并到dplyr管道中?

此时,我的dplyr管道如下所示:

df <- df %>%
    select(relevant columns that I need)
Run Code Online (Sandbox Code Playgroud)

之后,我被困在这里并使用方括号[]来对非NA列进行子集化.

谢谢!非常感激.

Ron*_*hah 11

我们可以使用一个版本 select_if

library(dplyr)
df %>%
   select_if(function(x) !(all(is.na(x)) | all(x=="")))

#  id Q2 Q3 Q4
#1  1  1 NA   
#2  2     2   
#3  3  4  3  2
#4  4  5  4  2
Run Code Online (Sandbox Code Playgroud)

您也可以将apply声明修改为

df %>% select_if(~!(all(is.na(.)) | all(. == "")))
Run Code Online (Sandbox Code Playgroud)


Ric*_*ord 10

dplyr1.0 版本中,您可以在where()内部使用 helper 函数,select而无需使用select_if.

library(tidyverse)
df <- data.frame(id = c(1, 2, 3, 4),
                 Q1 = c(1, "", 4, 5), 
                 Q2 = c(NA, NA, NA, NA),
                 Q3 = c(NA, 2, 3, 4), 
                 Q4 = c("", "", 2, 2), 
                 Q5 = c("", "", "", ""))

df %>% select(where(~ !(all(is.na(.)) | all(. == ""))))
#>   id Q1 Q3 Q4
#> 1  1  1 NA   
#> 2  2     2   
#> 3  3  4  3  2
#> 4  4  5  4  2
Run Code Online (Sandbox Code Playgroud)


Nik*_*aim 5

您可以select_if用来执行此操作。

方法:

col_selector <- function(x) {
  return(!(all(is.na(x)) | all(x == "")))
}


df %>% select_if(col_selector)
Run Code Online (Sandbox Code Playgroud)

输出:

  id Q2 Q3 Q4
1  1  1 NA   
2  2     2   
3  3  4  3  2
4  4  5  4  2
Run Code Online (Sandbox Code Playgroud)