Home > Blockchain >  Calculate within nested list in R
Calculate within nested list in R

Time:11-01

How do I calculate the sum of the count per city in nested lists and store it in a new tibble using map?

The output of the nested lists looks like this:


City:'s-Hertogenbosch`

$`'s-Hertogenbosch`$`5392`

$`'s-Hertogenbosch`$`5392`$men

 A tibble: 20 x 2

   age              count
   <chr>            <dbl>
 1 0 tot 5 jaar        20
 2 5 tot 10 jaar       40
 3 10 tot 15 jaar      45
 4 15 tot 20 jaar      20
 5 20 tot 25 jaar      25


$`'s-Hertogenbosch`$`5392`$women
 A tibble: 20 x 2
   age              count
   <chr>            <dbl>
 1 0 tot 5 jaar        15
 2 5 tot 10 jaar       30
 3 10 tot 15 jaar      35
 4 15 tot 20 jaar      30
 5 20 tot 25 jaar      15



City:'Aa en Hunze`
$`Aa en Hunze`
$`Aa en Hunze`$`9443`
$`Aa en Hunze`$`9443`$men
 A tibble: 20 x 2
   age              count
   <chr>            <dbl>
 1 0 tot 5 jaar         0
 2 5 tot 10 jaar       10
 3 10 tot 15 jaar       5
 4 15 tot 20 jaar       5
 5 20 tot 25 jaar       5


$`Aa en Hunze`$`9443`$women
 A tibble: 20 x 2
   age              count
   <chr>            <dbl>
 1 0 tot 5 jaar         5
 2 5 tot 10 jaar        5
 3 10 tot 15 jaar       5
 4 15 tot 20 jaar      10
 5 20 tot 25 jaar       5

I know how to store 1 specific postal code in a tibble:


sum of count <- tibble(sum(data[[1]][[1]][[1]]['count']))

But i can't figure out how to apply this for all lists in R using map:


Get_count_per_postal <- map_int(data, function(x){
    tibble(municipality = names(data), count_inhibitants = sum(data[[?]][[?]][[?]]['count']))
  })

I'm having a hard time accessing the nested lists and apply a calculation, it would be great if someone set me on right path.

Edit:

`8044` = list(men = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(110, 
85, 60, 45, 20, 65, 130, 80, 70, 45, 25, 15, 15, 5, 0, 0, 0, 
0, 0, 0)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame")), women = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(105, 
80, 55, 35, 30, 105, 120, 80, 50, 35, 25, 10, 5, 5, 0, 0, 0, 
0, 0, 0)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame")), migration = c(western_migration_background = 120, 
non_western_migration_background = 195), households = c(single_households = 75, 
multi_person_households_without_kids = 130, multi_person_households_with_kids = 310
)), `8045` = list(men = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(0, 
0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0)), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame")), women = structure(list(
    age = c("0 tot 5 jaar", "5 tot 10 jaar", "10 tot 15 jaar", 
    "15 tot 20 jaar", "20 tot 25 jaar", "25 tot 30 jaar", "30 tot 35 jaar", 
    "35 tot 40 jaar", "40 tot 45 jaar", "45 tot 50 jaar", "50 tot 55 jaar", 
    "55 tot 60 jaar", "60 tot 65 jaar", "65 tot 70 jaar", "70 tot 75 jaar", 
    "75 tot 80 jaar", "80 tot 85 jaar", "85 tot 90 jaar", "90 tot 95 jaar", 
    "95 jaar of ouder"), count = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0)), row.names = c(NA, -20L
), class = c("tbl_df", "tbl", "data.frame")), migration = c(western_migration_background = 0, 
non_western_migration_background = 0), households = c(single_households = 5, 
multi_person_households_without_kids = 5, multi_person_households_with_kids = 5
))))

img of structure in R


> dput(sample(data, 1))
list(Alblasserdam = list(`2951` = list(men = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(355, 
360, 305, 335, 265, 285, 300, 255, 270, 310, 315, 300, 250, 260, 
320, 235, 145, 85, 40, 10)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")), women = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(335, 
360, 295, 290, 270, 315, 285, 265, 305, 330, 345, 310, 265, 320, 
345, 320, 205, 170, 90, 20)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")), migration = c(western_migration_background = 630, 
non_western_migration_background = 820), households = c(single_households = 1350, 
multi_person_households_without_kids = 1395, multi_person_households_with_kids = 1580
)), `2952` = list(men = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(30, 
35, 40, 40, 30, 20, 20, 25, 30, 45, 50, 30, 15, 20, 10, 10, 0, 
5, 0, 0)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame")), women = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(30, 
35, 40, 60, 25, 30, 25, 30, 35, 50, 40, 25, 25, 15, 10, 10, 5, 
5, 0, 0)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame")), migration = c(western_migration_background = 45, 
non_western_migration_background = 20), households = c(single_households = 70, 
multi_person_households_without_kids = 80, multi_person_households_with_kids = 175
)), `2953` = list(men = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(200, 
215, 200, 200, 175, 240, 200, 195, 180, 225, 275, 170, 125, 115, 
115, 85, 55, 25, 5, 0)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")), women = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(190, 
185, 215, 175, 175, 215, 190, 190, 210, 230, 215, 160, 120, 130, 
125, 120, 60, 30, 15, 0)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")), migration = c(western_migration_background = 510, 
non_western_migration_background = 600), households = c(single_households = 815, 
multi_person_households_without_kids = 650, multi_person_households_with_kids = 1010
)), `2954` = list(men = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(75, 
70, 105, 100, 115, 75, 50, 55, 85, 90, 120, 125, 125, 85, 60, 
25, 5, 5, 0, 0)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")), women = structure(list(age = c("0 tot 5 jaar", 
"5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar", 
"25 tot 30 jaar", "30 tot 35 jaar", "35 tot 40 jaar", "40 tot 45 jaar", 
"45 tot 50 jaar", "50 tot 55 jaar", "55 tot 60 jaar", "60 tot 65 jaar", 
"65 tot 70 jaar", "70 tot 75 jaar", "75 tot 80 jaar", "80 tot 85 jaar", 
"85 tot 90 jaar", "90 tot 95 jaar", "95 jaar of ouder"), count = c(50, 
90, 90, 105, 100, 50, 60, 60, 75, 100, 150, 110, 100, 75, 60, 
20, 15, 5, 0, 0)), row.names = c(NA, -20L), class = c("tbl_df", 
"tbl", "data.frame")), migration = c(western_migration_background = 160, 
non_western_migration_background = 105), households = c(single_households = 180, 
multi_person_households_without_kids = 345, multi_person_households_with_kids = 475
))))

Kr, Quido

CodePudding user response:

It is not clear clear about the structure correctly. Perhaps, a recursive option would work - use rrapply to change the structure by melting the nested list, then filter the column 'L4' having only 'count', unnest the list column 'value', do a group_by sum (if we don't want to include 'L3' i.e. sex as grouping, remove it to get the overall count per 'municipality'

library(rrapply)
library(dplyr)
library(tidyr)
rrapply(data, how = 'melt') %>%
    filter(L4 == 'count') %>% 
    unnest(value) %>%
    group_by(municipality = L1, sex = L3) %>%
    summarise(count_inhabitants = sum(value, na.rm = TRUE), .groups = 'drop')
# A tibble: 4 × 3
  municipality          sex   count_inhabitants
  <chr>                 <chr>             <dbl>
1 City:'Aa en Hunze     men                  25
2 City:'Aa en Hunze     women                30
3 City:'s-Hertogenbosch men                 150
4 City:'s-Hertogenbosch women               125

Update

Using the OP's data

library(purrr)
map_dfr(data, ~ map_dfr(.x, ~ map_dfr(.x[c("men", "women")],
    ~ sum(.x$count, na.rm = TRUE), .id = 'sex'), .id = 'id'),
     .id = 'municipality')
# A tibble: 4 × 4
  municipality id      men women
  <chr>        <chr> <dbl> <dbl>
1 Alblasserdam 2951   5000  5440
2 Alblasserdam 2952    455   495
3 Alblasserdam 2953   3000  2950
4 Alblasserdam 2954   1370  1315

data

data <- list(`City:'s-Hertogenbosch` = list(`'s-Hertogenbosch$5392` = list(
    men = structure(list(age = c("0 tot 5 jaar", "5 tot 10 jaar", 
    "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar"), count = c(20, 
    40, 45, 20, 25)), class = c("tbl_df", "tbl", "data.frame"
    ), row.names = c(NA, -5L)), women = structure(list(age = c("0 tot 5 jaar", 
    "5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar"
    ), count = c(15, 30, 35, 30, 15)), class = c("tbl_df", "tbl", 
    "data.frame"), row.names = c(NA, -5L)))), `City:'Aa en Hunze` = list(
    `'Aa en Hunze$9443` = list(men = structure(list(age = c("0 tot 5 jaar", 
    "5 tot 10 jaar", "10 tot 15 jaar", "15 tot 20 jaar", "20 tot 25 jaar"
    ), count = c(0, 10, 5, 5, 5)), class = c("tbl_df", "tbl", 
    "data.frame"), row.names = c(NA, -5L)), women = structure(list(
        age = c("0 tot 5 jaar", "5 tot 10 jaar", "10 tot 15 jaar", 
        "15 tot 20 jaar", "20 tot 25 jaar"), count = c(5, 5, 
        5, 10, 5)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
    -5L)))))
  • Related