Выбор группы строк, если одна из них имеет нужный атрибут

У меня есть такой фрейм данных:

data <- data.frame(family.id=rep(1:6, each=5), 
                   member.id=rep(1:5, times=6), 
                   attribute=c(1, 1, 2, 3, 4, 1, 2, 2, 3, 5, 1, 1, 3, 5, 5, 2, 
                               3, 3, 4, 5, 1, 1, 4, 4, 5, 3, 3, 4, 5, 5))

Я хочу выбрать всех членов домохозяйства, если хотя бы один из них имеет атрибут, равный 4. скажите пожалуйста, что мне делать?

Я предпочитаю использовать команду «group_by» из dplyr.


1
61
4

Ответы:

Решено
library(tidyverse)

data %>% 
      filter(any(attribute == 4), .by = family.id)

или

data %>% 
  group_by(family.id) %>% 
  filter(any(attribute == 4)) %>% 
  ungroup()

   family.id member.id attribute
1          1         1         1
2          1         2         1
3          1         3         2
4          1         4         3
5          1         5         4
6          4         1         2
7          4         2         3
8          4         3         3
9          4         4         4
10         4         5         5
11         5         1         1
12         5         2         1
13         5         3         4
14         5         4         4
15         5         5         5
16         6         1         3
17         6         2         3
18         6         3         4
19         6         4         5
20         6         5         5

Вы можете использовать subset + ave, если используете основание R.

> subset(data, ave(attribute == 4, family.id) > 0)
   family.id member.id attribute
1          1         1         1
2          1         2         1
3          1         3         2
4          1         4         3
5          1         5         4
16         4         1         2
17         4         2         3
18         4         3         3
19         4         4         4
20         4         5         5
21         5         1         1
22         5         2         1
23         5         3         4
24         5         4         4
25         5         5         5
26         6         1         3
27         6         2         3
28         6         3         4
29         6         4         5
30         6         5         5

ave или subset:

data[as.logical(with(data, ave(attribute, family.id, FUN = \(x) any(x==4L)))), ]
# or
subset(data, family.id %in% unique(family.id[attribute==4L]))

В базе должен быть более лаконичный вариант, пока не вспомнил.


Используя any в subset,

> subset(data, ave(attribute == 4, family.id, FUN=any))
   family.id member.id attribute
1          1         1         1
2          1         2         1
3          1         3         2
4          1         4         3
5          1         5         4
16         4         1         2
17         4         2         3
18         4         3         3
19         4         4         4
20         4         5         5
21         5         1         1
22         5         2         1
23         5         3         4
24         5         4         4
25         5         5         5
26         6         1         3
27         6         2         3
28         6         3         4
29         6         4         5
30         6         5         5

кронштейны,

> data[with(data, family.id %in% family.id[attribute == 4]), ]
   family.id member.id attribute
1          1         1         1
2          1         2         1
3          1         3         2
4          1         4         3
5          1         5         4
16         4         1         2
17         4         2         3
18         4         3         3
19         4         4         4
20         4         5         5
21         5         1         1
22         5         2         1
23         5         3         4
24         5         4         4
25         5         5         5
26         6         1         3
27         6         2         3
28         6         3         4
29         6         4         5
30         6         5         5

Таблица данных,

> library(data.table)
> setDT(data)[family.id %in% family.id[attribute == 4], ]
    family.id member.id attribute
        <int>     <int>     <num>
 1:         1         1         1
 2:         1         2         1
 3:         1         3         2
 4:         1         4         3
 5:         1         5         4
 6:         4         1         2
 7:         4         2         3
 8:         4         3         3
 9:         4         4         4
10:         4         5         5
11:         5         1         1
12:         5         2         1
13:         5         3         4
14:         5         4         4
15:         5         5         5
16:         6         1         3
17:         6         2         3
18:         6         3         4
19:         6         4         5
20:         6         5         5
    family.id member.id attribute

или

> setDT(data)[, if (4 %in% attribute) .SD, by = family.id]
    family.id member.id attribute
        <int>     <int>     <num>
 1:         1         1         1
 2:         1         2         1
 3:         1         3         2
 4:         1         4         3
 5:         1         5         4
 6:         4         1         2
 7:         4         2         3
 8:         4         3         3
 9:         4         4         4
10:         4         5         5
11:         5         1         1
12:         5         2         1
13:         5         3         4
14:         5         4         4
15:         5         5         5
16:         6         1         3
17:         6         2         3
18:         6         3         4
19:         6         4         5
20:         6         5         5
    family.id member.id attribute