我有一个问题要解决如何在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 |
答案 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 的最后一行。