如果在dplyr

时间:2017-05-09 22:24:43

标签: r dataframe filter dplyr

我想从数据框中删除整行,如果它们具有所有NA但仅用于某些列的子集(在序列中命名以及以“X”开头)。

这与我从我所知道的其他SO答案不同,因为我无法通过名称(太多变量)手动引用每一列,并且如果它们完全是NA,则不仅要删除行(而是如果一些变量完全是NA)。

所以转动样本数据:

data1 <- as.data.frame(rbind(c(1,2,3), c(1, NA, 4), c(4,6,7), c(1, NA, NA), c(4, 8, NA))) 
colnames(data1) <- c("Z","X1","X2")
data1
 Z X1 X2
1 1  2  3
2 1 NA  4
3 4  6  7
4 1 NA NA
5 4  8 NA

成:

  V1 V2 V3
1  1  2  3
2  1 NA  4
3  4  6  7
4  4  8 NA

即。如果X1和X2(所有X序列)都是NA,则删除该行。

在这个例子中,为了方便起见,只有两个变量(X1:X2),但实际上我接近100个这个序列和许多其他重要的变量,可能是也可能不是NA。我更愿意在dplyr中使用过滤器,但其他解决方案也会受到赞赏。

我觉得:

data2 %>% filter(!is.na(all(X1:X2)))

或类似的东西是接近但R不喜欢过滤器中X1:X2的序列引用。

2 个答案:

答案 0 :(得分:4)

您可以使用rowSums + select + starts_with + filter

data1 %>% 
    filter(rowSums(!is.na(select(., starts_with("X")))) != 0)

#  Z X1 X2
#1 1  2  3
#2 1 NA  4
#3 4  6  7
#4 4  8 NA

答案 1 :(得分:1)

使用apply的基础R解决方案将是:

drop <- which(apply(data1[,startsWith(colnames(data1), "X")], 1, function(x) all(is.na(x))))
data1[-drop,]
#  Z X1 X2
#1 1  2  3
#2 1 NA  4
#3 4  6  7
#5 4  8 NA

使用rowSums的另一个选项:

drop <- which(rowSums(is.na(data1[,c("X1","X2")]))>=2)
data1[-drop]