仅当所有值均为0或NA时才删除行

时间:2018-03-07 21:49:34

标签: r

如果我有一行包括:

0   NA  0   NA  0   NA  NA
0   1   0   0   0   1   0
0   NA  1   0   0   0   0

我想摆脱只有第一行而不是第二行或第三行,它们至少有一个非零字符。我该怎么做?

我已经检查了使用is.na函数的子集,但是删除了具有NA值的任何行。我也无法改变数据集本身,因为0有时意味着什么。

4 个答案:

答案 0 :(得分:2)

我会避免使用apply(m,1,...),因为它对任何合理的大数据都会很慢。 rowSums通常适用于这类任务:

m[rowSums(m != 0, na.rm=TRUE) > 0,]
#     V1 V2 V3 V4 V5 V6 V7
#[1,]  0  1  0  0  0  1  0
#[2,]  0 NA  1  0  0  0  0

m的位置:

m <- as.matrix(read.table(text="0   NA  0   NA  0   NA  NA
0   1   0   0   0   1   0
0   NA  1   0   0   0   0"))

答案 1 :(得分:1)

以下是工作:

is_valid <- function(my_row){
    any(my_row!=0, na.rm = TRUE)
}

valid_df <- df[which(apply(df, 1, FUN = is_valid)),]

valid_df
  V1 V2 V3 V4 V5 V6 V7
2  0  1  0  0  0  1  0
3  0 NA  1  0  0  0  0

答案 2 :(得分:1)

下面将函数应用于每一行,如果每个元素都是0或NA,则基本上只返回true,然后检查它们是否都是其中之一。第二个参数1仅表示应用于行2表示适用于列

goodRows <- apply(df, 1, function(x){sum(x %in% c(0,NA)) != length(x)})

df <- df[goodRows,]

如果你想要一行解决方案,goodRows位可以直接取出并直接放在df row参数中:)

df <- df[apply(df, 1, function(x){sum(x %in% c(0,NA)) != length(x)}),]

此解决方案的优点是,因为我们不在任何函数中使用na.rm,您可以将向量c(0,NA)更改为您想要的任何内容。稍后您可能还想删除-1,例如。

答案 3 :(得分:0)

使用dplyr

library(dplyr)
df <- data_frame(a = c(0, NA, 0, 4, NA, 0), b = c(1, NA, 0, 4, NA, 0), c = c(1, 0, 1, NA, NA, 0))

> df
# A tibble: 6 x 3
  a     b     c
  <dbl> <dbl> <dbl>
1     0     1     1
2    NA    NA     0
3     0     0     1
4     4     4    NA
5    NA    NA    NA
6     0     0     0

df %>% 
  filter(rowSums(., na.rm = T) != 0)

# A tibble: 3 x 3
  a     b     c
  <dbl> <dbl> <dbl>
1     0     1     1
2     0     0     1
3     4     4    NA

如果你只关心测试某些列(例如a和b),你可以使用select

df %>% 
  filter(rowSums(select(., a, b), na.rm = T) != 0) 

# A tibble: 2 x 3
  a     b     c
  <dbl> <dbl> <dbl>
1     0     1     1
2     4     4    NA