使用R:根据不同的条件有效地删除行

问题描述

考虑这个样本

df<-{data.frame(v0=c(1,2,5,1,5),v1=c('a','a','b','c','a'),v2=c(0,10,8,3,5))}

对于大型数据帧:如果 v0>4,删除所有包含对应值 v1 的行(删除一个组?)。

因此,这里的结果应该是一个数据框,删除所有带有“a”的行,因为“a”的 v0 值为 5。

df_ExpectedResult<-{data.frame(v0=c( 1,2 ),v1=c( 'b','b'),v2=c(1,3))} 

另外,我想要一个新的数据框来保存删除的组。

df_Dropped <- {data.frame(v1='a')}

对于庞大的数据集,您将如何有效地执行此操作?我使用了一个简单的 for 循环和 if 语句,但操作时间太长。

解决方法

使用 subset + ave 的基本 R 选项

subset(df,!ave(v0 > 4,v1,FUN = any))

给予

  v0 v1 v2
4  1  b  1
5  2  b  8
6  0  c  5
7  1  c 10
8  2  b  3
9  2  b  3
,

带有 dplyr 的选项

library(dplyr)
df %>%
    group_by(v1) %>%
    filter(sum(v0 > 4) < 1) %>%
    ungroup

-输出

# A tibble: 6 x 3
#     v0 v1       v2
#  <dbl> <chr> <dbl>
#1     1 b         1
#2     2 b         8
#3     0 c         5
#4     1 c        10
#5     2 b         3
#6     2 b         3
,

这是两个操作,但是这个呢:

drop_groups <- df %>% filter(v0 > 4) %>% select(v1) %>% unique()
df_result <- df %>% filter(!(v1 %in% drop_groups))
df_result
#   v0 v1 v2
# 1  1  b  1
# 2  2  b  8
# 3  0  c  5
# 4  1  c 10
# 5  2  b  3
# 6  2  b  3