如何在R中删除零值的行?

时间:2012-04-02 13:48:26

标签: r rows zero

我有一个问题要解决如何在R中删除零值的行。在另一方面,我可以使用na.omit()删除所有NA值或使用complete.cases()删除包含的行NA值。

有没有人知道如何删除R中零值的行?

例如:

之前

|    DateTime      | Mac1  | Mac2  | Mac3  | Mac4  |
----------------------------------------------------
| 2011-04-02 06:00 | 20    | 0     | 20    | 20    |  
| 2011-04-02 06:05 | 21    | 21    | 21    | 21    |  
| 2011-04-02 06:10 | 22    | 22    | 22    | 22    |  
| 2011-04-02 06:15 | 23    | 23    | 0     | 23    |  
| 2011-04-02 06:20 | 24    | 24    | 24    | 24    | 
| 2011-04-02 06:25 | 0     | 25    | 25    | 0     | 

|    DateTime      | Mac1  | Mac2  | Mac3  | Mac4  |
----------------------------------------------------
| 2011-04-02 06:05 | 21    | 21    | 21    | 21    |  
| 2011-04-02 06:10 | 22    | 22    | 22    | 22    |  
| 2011-04-02 06:20 | 24    | 24    | 24    | 24    |  

9 个答案:

答案 0 :(得分:33)

有几种不同的方法可以做到这一点。我更喜欢使用apply,因为它很容易扩展:

##Generate some data
dd = data.frame(a = 1:4, b= 1:0, c=0:3)

##Go through each row and determine if a value is zero
row_sub = apply(dd, 1, function(row) all(row !=0 ))
##Subset as usual
dd[row_sub,]

答案 1 :(得分:7)

好吧,您可以将0替换为NA,然后使用其中一种解决方案,但为了区别,您可能会注意到一个数字只有一个有限的对数,如果它大于0,因此如果一行中没有零,rowSums的{​​{1}}只会是有限的。

log

答案 2 :(得分:5)

我可能会考虑Joran建议用NAs替换0,然后使用你提到的内置函数。如果你不能/不想这样做,一种方法是使用any()来查找包含0的行并将其子集化为:

set.seed(42)
#Fake data
x <- data.frame(a = sample(0:2, 5, TRUE), b = sample(0:2, 5, TRUE))
> x
  a b
1 2 1
2 2 2
3 0 0
4 2 1
5 1 2
#Subset out any rows with a 0 in them
#Note the negation with ! around the apply function
x[!(apply(x, 1, function(y) any(y == 0))),]
  a b
1 2 1
2 2 2
4 2 1
5 1 2

要实现Joran的方法,这样的事情应该让你开始:

x[x==0] <- NA

答案 3 :(得分:4)

您可以使用dplyr软件包中的过滤器。

让我们将您的数据框称为df

validates :avatar, presence: true, blob: { content_type: :image } validates :photos, presence: true, blob: { content_type: ['image/png', 'image/jpg', 'image/jpeg'], size_range: 1..5.megabytes }

df1仅包含条目大于零的行。希望这可以帮助。

答案 4 :(得分:3)

我会做以下事情。

将零设置为NA。

 data[data==0] <- NA
 data

删除与NA关联的行。

 data2<-data[complete.cases(data),]

答案 5 :(得分:1)

我更喜欢简单地改编csgillespie的方法,而不需要函数定义:

d[apply(d!=0, 1, all),]

其中d是您的数据框。

答案 6 :(得分:0)

在基数R中,我们可以使用grep选择要测试的列,将数据与0进行比较,使用rowSums选择具有所有非零值的行。

cols <- grep("^Mac", names(df))
df[rowSums(df[cols] != 0) == length(cols), ]

#          DateTime Mac1 Mac2 Mac3 Mac4
#1 2011-04-02 06:05   21   21   21   21
#2 2011-04-02 06:10   22   22   22   22
#3 2011-04-02 06:20   24   24   24   24

使用倒置逻辑来做到这一点,但给出相同的输出

df[rowSums(df[cols] == 0) == 0, ]

dplyr中,我们可以使用filter_at测试特定的列,并使用all_vars选择所有值都不等于0的行。

library(dplyr)
df %>%  filter_at(vars(starts_with("Mac")), all_vars(. != 0))

数据

df <- structure(list(DateTime = structure(1:6, .Label = c("2011-04-02 06:00", 
"2011-04-02 06:05", "2011-04-02 06:10", "2011-04-02 06:15", "2011-04-02 06:20", 
"2011-04-02 06:25"), class = "factor"), Mac1 = c(20L, 21L, 22L, 
23L, 24L, 0L), Mac2 = c(0L, 21L, 22L, 23L, 24L, 25L), Mac3 = c(20L, 
21L, 22L, 0L, 24L, 25L), Mac4 = c(20L, 21L, 22L, 23L, 24L, 0L
)), class = "data.frame", row.names = c(NA, -6L))

答案 7 :(得分:0)

使用tidyverse / dplyr,您还可以删除变量子集中具有零值的行:

data-game

答案 8 :(得分:0)

由于 dplyr 1.0.0 弃用了@Feng Mai 很好地展示的范围变体,这里是新语法的更新。这可能很有用,因为在这种情况下,across() 不起作用,我花了一些时间来找出如下解决方案。

目标是提取一列中至少包含一个 0 的所有行。

df %>% 
  rowwise() %>% 
  filter(any(c_across(everything(.)) == 0))

数据

df <- data.frame(a = 1:4, b= 1:0, c=0:3)
df <- rbind(df, c(0,0,0))
df <- rbind(df, c(9,9,9))

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

因此它不会正确返回包含所有 9 的最后一行。