我有一个广泛格式的参与者问卷答复数据框,每列代表一个特定的问题/项目。
数据框看起来像这样:
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)
我希望R删除在每个行中具有(1)NA或(2)空白的所有值的列。因此,我不希望列Q1(完全由NAs组成)和列Q5(完全由“”组成的空白组成)。
根据此thread,我可以使用以下内容删除完全由NA组成的列:
df[, !apply(is.na(df), 2, all]
但是,该解决方案不会解决空白(“”)。当我在dplyr管道中执行所有这些操作时,是否还有人可以解释如何将上述代码合并到dplyr管道中?
此时,我的dplyr管道如下所示:
df <- df %>%
select(relevant columns that I need)
之后,我被困在这里并使用方括号[]来对非NA列进行子集化。
谢谢!非常感谢。
答案 0 :(得分:10)
我们可以使用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
您还可以将apply
声明修改为
df[!apply(df, 2, function(x) all(is.na(x)) | all(x==""))]
答案 1 :(得分:5)
您可以使用select_if
执行此操作。
方法:
col_selector <- function(x) {
return(!(all(is.na(x)) | all(x == "")))
}
df %>% select_if(col_selector)
输出:
id Q2 Q3 Q4
1 1 1 NA
2 2 2
3 3 4 3 2
4 4 5 4 2
答案 2 :(得分:3)
在dplyr
1.0版中,您可以在where()
内使用辅助函数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