dplyr: 如何按子组标准过滤组?

3

我的问题与这个类似,但过滤条件不同。

> demo(dadmom,package="tidyr")

> library(tidyr)
> library(dplyr)

> dadmom <- foreign::read.dta("http://www.ats.ucla.edu/stat/stata/modules/dadmomw.dta")

> dadmom %>%
+   gather(key, value, named:incm) %>%
+   separate(key, c("variable", "type"), -2) %>%
+   spread(variable, value, convert = TRUE)
  famid type   inc name
1     1    d 30000 Bill
2     1    m 15000 Bess
3     2    d 22000  Art
4     2    m 18000  Amy
5     3    d 25000 Paul
6     3    m 50000  Pat

使用原始表格中的 "incm",很容易分辨出收入大于20000元的妈妈所在的家庭:

> dadmom
  famid named  incd namem  incm
1     1  Bill 30000  Bess 15000
2     2   Art 22000   Amy 18000
3     3  Paul 25000   Pat 50000

问题是:如何从“整理过的”数据中进行操作?

dplyr::filter(data, type == "m" & inc > 20000) - Rich Scriven
只返回一行。我想要整个组(m和d)。 - Dong
1个回答

4
您可以在代码中添加group_byfilter
#OP's code
d1 <- dadmom %>%
           gather(key, value, named:incm) %>%
           separate(key, c("variable", "type"), -2) %>%
           spread(variable, value, convert = TRUE)

 d1 %>% 
    group_by(famid) %>%
    filter(all(sum(type=='m' & inc > 15000)==sum(type=='m')))

#    famid type   inc name
# 1     2    d 22000  Art
# 2     2    m 18000  Amy
# 3     3    d 25000 Paul
# 4     3    m 50000  Pat

注意: 当famid中有多个'm'时,以上方法也适用(更加通用)

对于每个famid只有一个'm/f'对的普通情况

 d1 %>%
     group_by(famid) %>% 
     filter(any(inc >15000 & type=='m'))
 #   famid type   inc name
 #1     2    d 22000  Art
 #2     2    m 18000  Amy
 #3     3    d 25000 Paul
 #4     3    m 50000  Pat

此外,如果您想使用,可以从开发版本的中获取多个值列。它可以从此处安装。请保留HTML标记。
 library(data.table)
 melt(setDT(dadmom), measure.vars=list(c(2,4), c(3,5)), 
    variable.name='type', value.name=c('name', 'inc'))[,
    type:=c('d', 'm')[type]][, .SD[any(type=='m' & inc >15000)] ,famid]
 #    famid type name   inc
 #1:     2    d  Art 22000
 #2:     2    m  Amy 18000
 #3:     3    d Paul 25000
 #4:     3    m  Pat 50000

谢谢。我不知道“any”和“all”。它们是高效的函数吗?我问这个问题是因为我的实际数据将有许多组,以及组内的许多行(虽然非常规则,数量和顺序固定)。 - Dong
@Dong 我这么认为。你的数据集有多大? - akrun
现在不算太大。整理后, ~(7x200k) --> (7x400k)。目前有约100k个组,就像使用 group_by(famid) 得到的那些组一样,每个组有4行。但随着我收集更多实验数据,数据的宽度和长度都会增加。 - Dong
@Dong 只是一个想法,如果数据量很大,在进行 gather 之前进行子集处理是否更好(尚未进行基准测试)。 - akrun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接