#r #group-by #tidyverse #dplyr
#r #группировать по #tidyverse #dplyr
Вопрос:
У меня есть длинная таблица с повторяющимися комбинациями area
и cluster
.
counts <- tibble::tribble(
~age, ~area, ~cluster, ~norm.to.area,
"gw_25", "cingulate", "cluster_1", 0.03,
"gw_20", "cingulate", "cluster_1", 0.03,
"gw_18", "hippocampus", "cluster_1", 0.02,
"gw_25", "insula", "cluster_1", 0.01,
"gw_20", "motor", "cluster_1", 0.01,
"gw_22", "motor", "cluster_1", 0.01,
"gw_25", "motor", "cluster_1", 0.01,
"gw_14", "motor", "cluster_1", 0.01,
"gw_18", "motor", "cluster_1", 0.01,
"gw_19", "motor", "cluster_1", 0.01,
"gw_17", "motor", "cluster_1", 0.01,
"gw_20", "occipital", "cluster_1", 0.01,
"gw_17", "occipital", "cluster_1", 0.01,
"gw_18", "occipital", "cluster_1", 0.01,
"gw_19", "occipital", "cluster_1", 0.01,
"gw_22", "occipital", "cluster_1", 0.01,
"gw_14", "occipital", "cluster_1", 0.01,
"gw_22", "parietal", "cluster_1", 0,
"gw_25", "parietal", "cluster_1", 0,
"gw_17", "parietal", "cluster_1", 0,
"gw_19", "parietal", "cluster_1", 0,
"gw_20", "parietal", "cluster_1", 0,
"gw_20", "PFC", "cluster_1", 0.01,
"gw_22", "PFC", "cluster_1", 0.01,
"gw_25", "PFC", "cluster_1", 0.01
)
Я хочу создать новую переменную, sum.norm.to.area
, которая является суммой norm.to.area
для каждого cluster
, используя значение norm.to.area
только ОДИН РАЗ для каждой комбинации area / subcluster.merge
.
Я пытался group_by
cluster
, но это суммирует значения столько раз, сколько появляется данная комбинация.
counts %>% group_by(cluster) %>% mutate(sum.norm.to.area = sum(norm.to.area)
Спасибо за ваш совет.
ОБНОВЛЕНИЕ 1:
Пробовал использовать summary, как предложено ниже, но происходит то же самое (за исключением, конечно, без добавления в качестве нового столбца):
> counts %>% group_by(subcluster.merge, area) %>% summarize(sum(norm.to.area))
tibble::tribble(
~cluster . , ~area, ~sum.norm.to.area.,
"cluster_1", "PFC", 0.06,
"cluster_1", "somatosensory", 0.05,
"cluster_1", "motor", 0.07,
"cluster_1", "parietal", 0,
"cluster_1", "temporal", 0.03,
"cluster_1", "occipital", 0.06,
"cluster_1", "hippocampus", 0.02,
"cluster_1", "insula", 0.01,
"cluster_1", "cingulate", 0.06,
"cluster_10-34", "PFC", 0.42,
"cluster_10-34", "somatosensory", 0.35,
"cluster_10-34", "motor", 0.48,
"cluster_10-34", "parietal", 0.36,
"cluster_10-34", "temporal", 0.28,
"cluster_10-34", "occipital", 0.4,
"cluster_10-34", "hippocampus", 0.12,
"cluster_10-34", "insula", 0,
"cluster_10-34", "cingulate", 0,
"cluster_11", "PFC", 0.18,
"cluster_11", "somatosensory", 0.15,
"cluster_11", "motor", 0.14,
"cluster_11", "parietal", 0.12,
"cluster_11", "temporal", 0.04,
"cluster_11", "occipital", 0.18,
"cluster_11", "hippocampus", 0.02
)
ОБНОВЛЕНИЕ 2
Это тот результат, который я хочу, но способ, которым я к нему прихожу, слишком запутанный. Я хотел бы найти более простой способ, используя mutate и не используя join
.
> tmp <- counts %>% distinct(area, cluster, .keep_all = TRUE) %>%
add_count(cluster, wt = norm.to.area, name = "sum.norm.to.area")
counts %>% left_join(tmp, by = c("cluster", "area"))
Желаемый результат:
sum.norm.to.area
является результатом сложения norm.to.area
(только один раз) для всех уникальных комбинаций area
и cluster
:
tibble::tribble(
~age, ~area, ~cluster, ~norm.to.area, ~sum.norm.to.area,
"gw_25", "cingulate", "cluster_1", 0.03, 0.11,
"gw_20", "cingulate", "cluster_1", 0.03, 0.11,
"gw_18", "hippocampus", "cluster_1", 0.02, 0.11,
"gw_25", "insula", "cluster_1", 0.01, 0.11,
"gw_20", "motor", "cluster_1", 0.01, 0.11,
"gw_22", "motor", "cluster_1", 0.01, 0.11,
"gw_25", "motor", "cluster_1", 0.01, 0.11,
"gw_14", "motor", "cluster_1", 0.01, 0.11,
"gw_18", "motor", "cluster_1", 0.01, 0.11,
"gw_19", "motor", "cluster_1", 0.01, 0.11,
"gw_17", "motor", "cluster_1", 0.01, 0.11,
"gw_20", "occipital", "cluster_1", 0.01, 0.11,
"gw_17", "occipital", "cluster_1", 0.01, 0.11,
"gw_18", "occipital", "cluster_1", 0.01, 0.11,
"gw_19", "occipital", "cluster_1", 0.01, 0.11,
"gw_22", "occipital", "cluster_1", 0.01, 0.11,
"gw_14", "occipital", "cluster_1", 0.01, 0.11,
"gw_22", "parietal", "cluster_1", 0, 0.11,
"gw_25", "parietal", "cluster_1", 0, 0.11,
"gw_17", "parietal", "cluster_1", 0, 0.11,
"gw_19", "parietal", "cluster_1", 0, 0.11,
"gw_20", "parietal", "cluster_1", 0, 0.11,
"gw_20", "PFC", "cluster_1", 0.01, 0.11,
"gw_22", "PFC", "cluster_1", 0.01, 0.11,
"gw_25", "PFC", "cluster_1", 0.01, 0.11,
"gw_18", "PFC", "cluster_1", 0.01, 0.11,
"gw_19", "PFC", "cluster_1", 0.01, 0.11,
"gw_17", "PFC", "cluster_1", 0.01, 0.11,
"gw_22", "somatosensory", "cluster_1", 0.01, 0.11,
"gw_20", "somatosensory", "cluster_1", 0.01, 0.11,
"gw_25", "somatosensory", "cluster_1", 0.01, 0.11,
"gw_18", "somatosensory", "cluster_1", 0.01, 0.11,
"gw_19", "somatosensory", "cluster_1", 0.01, 0.11,
"gw_25", "temporal", "cluster_1", 0.01, 0.11,
"gw_19", "temporal", "cluster_1", 0.01, 0.11,
"gw_20", "temporal", "cluster_1", 0.01, 0.11
)
Комментарии:
1. почему все
sum.norm.to.area
одинаково? Как вы это вычисляете? Можете ли вы объяснить одно вычисление на примере?2. Для столбцов cluster_1 это сумма
norm.to.area
для всех уникальных значенийarea
. т. Е.0.03 0.02 0.01 0.01 0 0.01 ....
. Таким образом, вы добавляете каждую область только ОДИН РАЗ.3. тогда сумма не будет равна 0.09?
0.03 0.02 0.01 0.01 0.01 0.00 0.01 = 0.09
?4. Да, это только
head
для таблицы. Обновил его, чтобы показать всеcluster_1
строки.5. Я сомневаюсь, что есть более простой способ сделать это, чем ваше обновление 2.
Ответ №1:
Используя dplyr
we can group_by
cluster
и sum
только уникальное значение в каждой area
.
library(dplyr)
counts %>%
group_by(cluster) %>%
mutate(sum.norm = sum(norm.to.area[!duplicated(area)]))
# age area cluster norm.to.area sum.norm
# <chr> <chr> <chr> <dbl> <dbl>
# 1 gw_25 cingulate cluster_1 0.03 0.09
# 2 gw_20 cingulate cluster_1 0.03 0.09
# 3 gw_18 hippocampus cluster_1 0.02 0.09
# 4 gw_25 insula cluster_1 0.01 0.09
# 5 gw_20 motor cluster_1 0.01 0.09
# 6 gw_22 motor cluster_1 0.01 0.09
# 7 gw_25 motor cluster_1 0.01 0.09
# 8 gw_14 motor cluster_1 0.01 0.09
# 9 gw_18 motor cluster_1 0.01 0.09
#10 gw_19 motor cluster_1 0.01 0.09
# … with 15 more rows
Комментарии:
1. Удивительные. Спасибо!
2. какие-либо причины, стоящие за понижением? Был бы рад это исправить.
3. Не уверен, откуда это взялось — я поддержал ваш ответ. Мои вопросы тоже были отклонены.. :/
Ответ №2:
Вместо mutate, я думаю, вы ищете summary()
counts %>% group_by(cluster, area) %>% summarize(sum.norm.to.area = sum(norm.to.area))
Комментарии:
1. Спасибо! Однако это все равно дает сумму всех строк с заданной комбинацией. См. Обновление .
2. Попробуйте это (я предполагаю, что в ваших данных больше 1 кластера) подсчитывает %>% select(-age) %>% unique() %>% group_by(cluster) %>% summary(sum.norm.to.area = sum(norm.to.area)). Уникальная функция избавит вас от повторяющихся строк, поскольку в случае вашего вопроса возраст больше не является особенно важной переменной, я прав?
3. Я хочу сохранить все переменные, включая возраст, в таблице.
4. Таким образом, вы ожидаете, что sum.norm.to.area также будет повторяющейся / повторяющейся последовательностью?
5. ДА. Для целей это должно быть так
ggplot
. Я добавил желаемый результат выше.