Суммировать переменную в сгруппированном фрейме данных только один раз для каждой уникальной комбинации двух других переменных с помощью dplyr

#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 . Я добавил желаемый результат выше.