Visualizing international demographic indicators with idbr and Plotly

[This article was first published on KYLE WALKER DATA, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

It’s been a while since I last posted here – but I’ve been working on a new R package that I’m quite excited about, and I thought this would be the right place to post. My new package, idbr, is an R interface to the United States Census Bureau’s International Data Base API. The IDB includes a host of international demographic indicators – including historical data and projections to 2050. I use IDB data all of the time for my teaching – and idbr makes the process of getting the data much easier! While this product uses the Census Bureau Data API, it is not endorsed or certified by the Census Bureau.

Install from CRAN with the following command:


To get started, you’ll need a Census API key; this can be obtained from if you don’t already have one. Before downloading data, set your API key for your idbr session with the set_api_key function:


idb_api_key('Your API key goes here')

There are two main functions in the idbr package. idb1 fetches population data by one-year age bands for one or more countries in one or more years, optionally by age ranges or by sex. idb5 has a lot more indicators available, including total fertility rate, life expectancy, and population by five-year age ranges. To view all of the variables available in the idb function, call idb_variables(). Groups of similar variables, termed concepts, can be fetched at once; see the available concepts with idb_concepts().

Below are some examples of how to use the package with Plotly’s fantastic new R client. Browse the code for idbr at, and please let me know if you have any feedback!

Please note: the embedded visualizations are crashing my browser on my mobile device, so I’ve set it so they won’t show up on phones. To view the graphics, take a look at the post on your computer.

World map of infant mortality rates by country for 2016:


df <- idb5(country = 'all', year = 2016, variable = 'IMR', country_name = TRUE)

plot_ly(df, z = IMR, text = NAME, locations = NAME, locationmode = 'country names',
        type = 'choropleth', colors = viridis(99), hoverinfo = 'text+z') %>%
  layout(title = 'Infant mortality rate (per 1000 live births), 2016', 
         geo = list(projection = list(type = 'robinson')))

Projected population pyramid of China in 2050:


male <- idb1('CH', 2050, sex = 'male') %>%
  mutate(POP = POP * -1,
         SEX = 'Male')

female <- idb1('CH', 2050, sex = 'female') %>%
  mutate(SEX = 'Female')

china <- rbind(male, female) %>%
  mutate(abs_pop = abs(POP))

plot_ly(china, x = POP, y = AGE, color = SEX, type = 'bar', orientation = 'h',
        hoverinfo = 'y+text+name', text = abs_pop, colors = c('red', 'gold')) %>%
  layout(bargap = 0.1, barmode = 'overlay',
         xaxis = list(tickmode = 'array', tickvals = c(-10000000, -5000000, 0, 5000000, 10000000),
         ticktext = c('10M', '5M', '0', '5M', '10M')), 
         title = 'Projected population structure of China, 2050')

Life expectancy at birth by sex compared in a Shiny app

First, get the data from idbr then save out (so you don’t have to call the API each time):

# setup.R


idb_api_key("Your API key here")

full <- idb5(country = 'all', year = '2016', variables = c('E0_F', 'E0_M'), country_name = TRUE)

save(full, file = 'idbr_data.rds')

Next, build the app:

# app.R



ui <- fluidPage(

  titlePanel("Life expectancy at birth by country and sex"),

                  "Select region to plot:",
                  choices = sort(unique(countrycode_data$region)),
                  selected = 'Northern Africa')


server <- function(input, output) {

  regiondf <- reactive({

    reg <- countrycode_data[countrycode_data$region == input$region, ]

    fips <- reg$fips104

    sub <- full %>%
      filter(FIPS %in% fips) %>%
      rename(Male = E0_M, Female = E0_F) %>%



  output$dumbbell <- renderPlotly({

    regiondf() %>%
      gather(Sex, value, Male, Female) %>%
      plot_ly(x = value, y = NAME, mode = 'lines',
              group = NAME, showlegend = FALSE, line = list(color = 'gray'),
              hovermode = FALSE, hoverinfo = 'none') %>%
      add_trace(x = value, y = NAME, color = Sex, mode = 'markers',
              colors = c('darkred', 'navy'), marker = list(size = 10)) %>%
      layout(xaxis = list(title = 'Life expectancy at birth'),
             yaxis = list(title = ''),
             margin = list(l = 120))



shinyApp(ui = ui, server = server)

To leave a comment for the author, please follow the link and comment on their blog: KYLE WALKER DATA. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)