简体   繁体   中英

Sum a variable in a grouped dataframe only once for each unique combination of two other variables with dplyr

I have a long table with repeating combinations of area and 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
      )

I want to create a new variable, sum.norm.to.area , which is the sum of norm.to.area for each cluster , using the value of norm.to.area only ONCE for each combination of area / subcluster.merge .

I've tried to group_by cluster , but this sums the values as many times as a given combination appears.

counts %>% group_by(cluster) %>% mutate(sum.norm.to.area = sum(norm.to.area)

Thanks for your advice.

UPDATE 1:

Tried using summarize as suggested below, but the same thing occurs (except, of course, without adding as a new column):

> 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
      )

UPDATE 2

This is the output that I want, but the way I'm arriving at it is too convoluted. I'd like to find an easier way using mutate and not having to use 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"))

Desired output: sum.norm.to.area is the result of adding norm.to.area (only once) for all unique combinations of area and 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
      )

Using dplyr we can group_by cluster and sum only the unique value in each 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

我认为您不是在寻找mutate()

counts %>% group_by(cluster, area) %>% summarize(sum.norm.to.area = sum(norm.to.area))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM