Я бы хотел сделать такой же лайк distinct(), но для групп. Вот пример:
data <- data.frame(
group = c(1, 1, 2, 3, 3, 4, 4, 5, 5),
procedure = c("A", "B", "A", "A", "B", "A", "X", "A", "X")
)
group procedure
1 1 A
2 1 B
3 2 A
4 3 A
5 3 B
6 4 A
7 4 X
8 5 A
9 5 X
Я ожидаю этого:
Примечание: group_id является промежуточным и не имеет значения:
group procedure group_id
<dbl> <chr> <int>
1 1 A 2
2 1 B 2
3 2 A 1
4 4 A 3
5 4 X 3
Я использую этот рабочий код:
library(dplyr)
library(tidyr)
data %>%
summarise(procedure = toString(sort(procedure)), .by = group) %>%
mutate(group_id = as.integer(factor(procedure))) %>%
distinct(group_id, .keep_all = TRUE) %>%
separate_rows(procedure)
Есть ли более прямой метод? Для контекста: мой набор данных содержит 23 000 строк с многочисленными группами, и мне нужно определить и оценить основного члена каждой группы. Поэтому я ищу способ эффективно различать и оценивать все уникальные группы. Не могли бы вы предложить подход, облегчающий эту оценку?
Может ли группа когда-либо иметь более одной процедуры, и если да, то будет ли другое (>=1) количество процедур отличать группу от другой группы?
Рассмотрим использование data %>% distinct(procedure). Мы получим A, B, X. Теперь я хочу сделать то же самое для группы 1, 2,3,4,5. Group1 — это AB, а группа 3 — это AB. Итак, эти две группы — это разные группы A B. Group_id — это просто переменная, не такая уж и важная?!
Ага, вы могли бы сделать больше напрямую data %>% summarise(procedure=toString(sort(procedure)), .by=group) %>% distinct(procedure, .keep_all=TRUE) %>% separate_rows(procedure), но для 23 тыс. строк это выглядит медленно.
@JonSpring Нет. В одной группе каждое значение различно. В одной группе не может быть AA, но AB C и т. д.





Мы можем table группой и subset не-дураками.
> subset(data1, group %in% rownames(unique(unclass(table(group, procedure)))))
group procedure
1 1 A
2 1 B
3 2 A
6 4 A
7 4 X
Мы могли бы обобщить это.
> distinct_groups <- function(data, ..., .by) {
+ g <- rev(sapply(match.call()[-(1:2)], deparse))
+ data[data[[g[1]]] %in% rownames(unique(unclass(table(data[g])))), ]
+ }
> data2
group procedure foo
1 1.0 A 1
2 1.0 B 1
3 2.0 A 1
4 3.0 A 1
5 3.0 B 1
6 3.1 A 2
7 3.1 B 2
8 4.0 A 1
9 4.0 X 1
10 5.0 A 1
11 5.0 X 1
> data2 |> distinct_groups(procedure, foo, .by=group)
group procedure foo
1 1.0 A 1
2 1.0 B 1
3 2.0 A 1
6 3.1 A 2
7 3.1 B 2
8 4.0 A 1
9 4.0 X 1
> data1 |> distinct_groups(procedure, .by=group)
group procedure
1 1 A
2 1 B
3 2 A
6 4 A
7 4 X
Данные:
> dput(data1)
structure(list(group = c(1, 1, 2, 3, 3, 3.1, 3.1, 4, 4, 5, 5),
procedure = c("A", "B", "A", "A", "B", "A", "B", "A", "X",
"A", "X"), foo = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L,
1L)), class = "data.frame", row.names = c("1", "2", "3",
"4", "5", "4.1", "5.1", "6", "7", "8", "9"))
> dput(data2)
structure(list(group = c(1, 1, 2, 3, 3, 3.1, 3.1, 4, 4, 5, 5),
procedure = c("A", "B", "A", "A", "B", "A", "B", "A", "X",
"A", "X"), foo = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L,
1L)), class = "data.frame", row.names = c(NA, -11L))
Спасибо. Это хорошо. Интересно, нет такой функции для получения отдельных групп? Что вы думаете? group_id это не так важно!
@TarJae Правда, сложно сказать так коротко и приятно.
Я не знаю, достаточно ли короткий для вас код.
data %>%
summarise(procedure = list(sort(procedure)), .by = group) %>%
filter(!duplicated(procedure)) %>%
unnest(procedure)
который дает
# A tibble: 5 × 2
group procedure
<dbl> <chr>
1 1 A
2 1 B
3 2 A
4 4 A
5 4 X
Я не понимаю, что представляет собой идентификатор вашей группы.