根据其他列中的因素删除组

Remove group based on factor in other column

我想根据 count 和 id 列的编号删除整个组的行。

    id count  group
1  244     1  black
2  244     2  black
3  244     3  black
4  333     1  black
5  333     2  black
6  582     1 yellow
7  582     2 yellow
8  582     3 yellow
9  676    10 yellow
10 676    11 yellow
11 676    12 yellow

例如,黑色组有两个 id 因子(244333),它们都以计数 1 开头(分别为 1, 2, 31, 2 ).

但是,yellow 组也有两个 id 因素(582676),但是它的第二个 id 676 not 开始计数 1(以 10 开头)。因此,我想删除数据框中的 all 行黄色。

期望的输出:

   id count group
1 244     1 black
2 244     2 black
3 244     3 black
4 333     1 black
5 333     2 black

创建数据框的代码:

id = as.factor(c(244, 244, 244, 333, 333, 
                 582, 582, 582, 676, 676, 676))   
count = c(1, 2, 3, 1, 2, 1, 2, 3, 10, 11, 12) 
group = as.factor(c("black", "black", "black", "black", "black", 
                    "yellow", "yellow","yellow", "yellow", "yellow", "yellow"))  
df = data.frame(id, count, group)   

我正在摸索如何实现这一目标 objective,但我并不满意。

更新示例

    id      id2 count  group
1  244 81308991     1  black
2  244 97881213     2  black
3  244 84929200     3  black
4  333 59742977     1  black
5  333 25048598     2  black
6  582 30902503     1 yellow
7  582 62598100     2 yellow
8  582 33639927     3 yellow
9  676 13531041    10 yellow
10 676 15731681    11 yellow
11 676 49423609    12 yellow

代码:

id = as.factor(c(244, 244, 244, 333, 333, 
                 582, 582, 582, 676, 676, 676))     
id2 = as.factor(c(81308991, 97881213, 84929200, 59742977, 25048598, 
                  30902503, 62598100, 33639927, 13531041, 15731681, 49423609))  
count = c(1, 2, 3, 1, 2, 1, 2, 3, 10, 11, 12) 
group = as.factor(c("black", "black", "black", "black", "black", 
                    "yellow", "yellow","yellow", "yellow", "yellow", "yellow"))  
df = data.frame(id, id2, count, group) 

您可以通过加载tidyverse

来使用dplyr包中的filter()功能
library(tidyverse)
df1 <- df %>%
  filter(group != "yellow")

> df1
   id count group
 1 244     1 black
 2 244     2 black
 3 244     3 black
 4 333     1 black
 5 333     2 black

我们需要先计算是否有不是以1开头的组,然后对整个进行过滤data.frame。这是 dplyr

的非最佳解决方案
library(dplyr)
group_by(df, group, id) %>% 
  ## see what group + id doesn't start with 1
  mutate(s = ifelse(first(count) != 1, 1, 0)) %>% 
  ## generalize to the whole group
  group_by(group) %>% 
  mutate(s = sum(s)) %>% 
  ## filter out groups
  filter(s == 0)

您可以使用 ave 仅使用基础 R 来完成此操作。诀窍是通过 id 找出子组 countmin 值,然后通过group。如果两个值都是 1,你想保留它们。

df[ave(ave(df$count, df$id, FUN = min), df$group, FUN = max) == 1,]
#   id count group
#1 244     1 black
#2 244     2 black
#3 244     3 black
#4 333     1 black
#5 333     2 black

注意:正如弗兰克评论的那样,如果相同的id可以出现在多个group中,请务必也使用df$id作为 df$group 在内部 ave