分组因子的条件过滤器 - dplyr

时间:2015-11-15 02:12:01

标签: r group-by dplyr

说我有这种数据帧:

   day value group type id
1    1   0.1     A    X  1
2    1   0.4     A    Y  1
3    2   0.2     A    X  3
4    2   0.5     A    Y  3
5    3   0.3     A    X  5
6    3   0.2     A    Y  6
7    1   0.1     B    X  3
8    1   0.3     B    Y  3
9    2   0.1     B    X 11
10   2   0.4     B    Y 10
11   3   0.2     B    X 12
12   3   0.3     B    Y 12
13   1   0.1     C    X 12
14   1   0.3     C    Y 12
15   2   0.3     C    X  5
16   2   0.2     C    Y  5
17   3   0.2     C    X  3
18   3   0.2     C    Y  2

数据:

library(dplyr)
df1 <- data.frame(
day = rep(1:3,6),
value = c(0.1,0.2,0.3,0.4,0.5,0.2,0.1,0.1,0.2,0.3,0.4,0.3, 0.1,0.3,0.2,0.3,0.2,0.2),
group = rep(LETTERS[1:3], each=6)
) %>% 
  arrange(group,day) %>% 
  mutate(type=rep(LETTERS[24:25],9),
         id = c(1,1,3,3,5,6,3,3,11,10,12,12,12,12,5,5,3,2))  

df1

我想根据条件过滤器过滤此数据帧。我想group_by(day, group),如果每个分组中的所有id都相等,我想filter输出Y类型的所有行,但保留X行。

我可以通过运行循环或通过数据帧子集的几个步骤来完成此操作,但我想知道dplyrdata.table中是否有一个/两个衬垫,我在某种程度上忽略了它。 / p>

这将是所需的输出:

   day value group type id
1    1   0.1     A    X  1
3    2   0.2     A    X  3
5    3   0.3     A    X  5
6    3   0.2     A    Y  6
7    1   0.1     B    X  3
9    2   0.1     B    X 11
10   2   0.4     B    Y 10
11   3   0.2     B    X 12
13   1   0.1     C    X 12
15   2   0.3     C    X  5
17   3   0.2     C    X  3
18   3   0.2     C    Y  2

4 个答案:

答案 0 :(得分:3)

与P Lapointe相似,我有以下内容。我最初想用all()检查所有id值是否相同,但是尝试失败了。所以,我选择使用diff()。使用mutate()我检查了每个组的所有id值是否相同。然后,我选择了没有check == TRUE and type == "Y"组合的行。最后,我删除了检查列。

group_by(df1, day, group) %>%
mutate(check = any(diff(id) == 0)) %>%
filter(!(check == TRUE & type == "Y")) %>%
select(-check)

#     day value  group  type    id
#   (int) (dbl) (fctr) (chr) (dbl)
#1      1   0.1      A     X     1
#2      2   0.2      A     X     3
#3      3   0.3      A     X     5
#4      3   0.2      A     Y     6
#5      1   0.1      B     X     3
#6      2   0.1      B     X    11
#7      2   0.4      B     Y    10
#8      3   0.2      B     X    12
#9      1   0.1      C     X    12
#10     2   0.3      C     X     5
#11     3   0.2      C     X     3
#12     3   0.2      C     Y     2

修改

与akrun沟通后,我修改了上面的代码。在这里。

group_by(df1, day, group) %>%
mutate(check = n_distinct(id) == 1) %>%
filter(!(check == TRUE & type == "Y")) %>%
select(-check)

答案 1 :(得分:3)

这是一行data.table

我们将'data.frame'转换为'data.table'(setDT(df1)),按'日','组',if length {{1}分组'id'的元素为1,我们得到Data.table(unique)行的子集,其中'type'为'X'或.SD获得else

.SD

或者如果'type'已经按照示例数据

进行了排序
library(data.table)#v1.9.6+
setDT(df1)[, if(uniqueN(id)==1) .SD[type=='X'] else .SD, .(day, group)]
#    day group value type id
# 1:   1     A   0.1    X  1
# 2:   2     A   0.2    X  3
# 3:   3     A   0.3    X  5
# 4:   3     A   0.2    Y  6
# 5:   1     B   0.1    X  3
# 6:   2     B   0.1    X 11
# 7:   2     B   0.4    Y 10
# 8:   3     B   0.2    X 12
# 9:   1     C   0.1    X 12
#10:   2     C   0.3    X  5
#11:   3     C   0.2    X  3
#12:   3     C   0.2    Y  2

如果没有订购,

unique(setDT(df1), by = c('day', 'group', 'id'))

数据

unique(setDT(df1)[order(group,day, id, type)],by = c('day', 'group' , 'id'))

答案 2 :(得分:1)

试试这个:

 df1 %>% group_by(day,group) %>% distinct(id)

您的原始数据已订购,所以没关系,否则请尝试

df1 %>% group_by(day, group) %>%
    arrange(group, day, type) %>% distinct(id) %>%
    ungroup %>%‌ ​arrange(group, day, type, id)

答案 3 :(得分:1)

以下是n的解决方案。

dplyr