我想删除这个数据帧中的行:

a)在所有列中包含NAs。下面是我的示例数据帧。

             gene hsap mmul mmus rnor cfam
1 ENSG00000208234    0   NA   NA   NA   NA
2 ENSG00000199674    0   2    2    2    2
3 ENSG00000221622    0   NA   NA   NA   NA
4 ENSG00000207604    0   NA   NA   1    2
5 ENSG00000207431    0   NA   NA   NA   NA
6 ENSG00000221312    0   1    2    3    2

基本上,我想获得如下所示的数据帧。

             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0   2    2    2    2
6 ENSG00000221312    0   1    2    3    2

b)只在某些列中包含NAs,所以我也可以得到这个结果:

             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0   2    2    2    2
4 ENSG00000207604    0   NA   NA   1    2
6 ENSG00000221312    0   1    2    3    2

当前回答

Dplyr 1.0.4引入了两个配套的过滤函数:if_any()和if_all()。在这种情况下,if_all()伴随函数将特别有用:

a)删除所有列中包含NAs的行

df %>% 
  filter(if_all(everything(), ~ !is.na(.x)))

这一行将只保留那些列中没有NAs的行。

b)删除仅在某些列中包含NAs的行

cols_to_check = c("rnor", "cfam")

df %>% 
  filter(if_all(cols_to_check, ~ !is.na(.x)))

这一行将检查任何指定的列(cols_to_check)是否有NAs,并只保留没有NAs的那些行。

其他回答

我更喜欢用下面的方法来检查行中是否包含NAs:

row.has.na <- apply(final, 1, function(x){any(is.na(x))})

这将返回逻辑向量,其中的值表示一行中是否有NA。你可以使用它来查看你需要删除多少行:

sum(row.has.na)

并最终放弃它们

final.filtered <- final[!row.has.na,]

对于过滤具有特定部分NAs的行,它变得有点棘手(例如,您可以将'final[,5:6]'输入到'apply')。 一般来说,Joris Meys的解决方案似乎更优雅。

Dplyr 1.0.4引入了两个配套的过滤函数:if_any()和if_all()。在这种情况下,if_all()伴随函数将特别有用:

a)删除所有列中包含NAs的行

df %>% 
  filter(if_all(everything(), ~ !is.na(.x)))

这一行将只保留那些列中没有NAs的行。

b)删除仅在某些列中包含NAs的行

cols_to_check = c("rnor", "cfam")

df %>% 
  filter(if_all(cols_to_check, ~ !is.na(.x)))

这一行将检查任何指定的列(cols_to_check)是否有NAs,并只保留没有NAs的那些行。

Tidyr有一个新函数drop_na:

library(tidyr)
df %>% drop_na()
#              gene hsap mmul mmus rnor cfam
# 2 ENSG00000199674    0    2    2    2    2
# 6 ENSG00000221312    0    1    2    3    2
df %>% drop_na(rnor, cfam)
#              gene hsap mmul mmus rnor cfam
# 2 ENSG00000199674    0    2    2    2    2
# 4 ENSG00000207604    0   NA   NA    1    2
# 6 ENSG00000221312    0    1    2    3    2
delete.dirt <- function(DF, dart=c('NA')) {
  dirty_rows <- apply(DF, 1, function(r) !any(r %in% dart))
  DF <- DF[dirty_rows, ]
}

mydata <- delete.dirt(mydata)

上面的函数删除数据帧中任何列中有'NA'的所有行,并返回结果数据。如果你想检查多个值,如NA和?将函数参数中的dart=c('NA')更改为dart=c('NA', '?')

关于你的第一个问题,我有一个我很熟悉的代码来摆脱所有NAs。感谢@Gregor让它变得更简单。

final[!(rowSums(is.na(final))),]

对于第二个问题,代码只是之前解决方案的一个替换。

final[as.logical((rowSums(is.na(final))-5)),]

注意-5是数据中的列数。这将消除具有所有NAs的行,因为rowsum加起来等于5,并且它们在减法后变为零。这一次,作为。逻辑是必要的。