(A) World Bank - wbstats

Load the package and the metadata

# load the package
library(wbstats)
# Extract the metadata
meta <- wb_cache()

Check the metadata content

# Show the names of the sublists within the obtained meta list
names(meta)
## [1] "countries"     "indicators"    "sources"       "topics"       
## [5] "regions"       "income_levels" "lending_types" "languages"
# Show one of the sublists: topics
meta$topics
## # A tibble: 21 × 3
##    topic_id topic                           topic_desc                          
##       <dbl> <chr>                           <chr>                               
##  1        1 Agriculture & Rural Development "For the 70 percent of the world's …
##  2        2 Aid Effectiveness               "Aid effectiveness is the impact th…
##  3        3 Economy & Growth                "Economic growth is central to econ…
##  4        4 Education                       "Education is one of the most power…
##  5        5 Energy & Mining                 "The world economy needs ever-incre…
##  6        6 Environment                     "Natural and man-made environmental…
##  7        7 Financial Sector                "An economy's financial markets are…
##  8        8 Health                          "Improving health is central to the…
##  9        9 Infrastructure                  "Infrastructure helps determine the…
## 10       10 Social Protection & Labor       "The supply of labor available in a…
## # ℹ 11 more rows

Show indicators info

# Show the top six rows for the indicators that contain "gdp"
gdp_vars <- wb_search("gdp") 
head(gdp_vars)
## # A tibble: 6 × 3
##   indicator_id       indicator                                    indicator_desc
##   <chr>              <chr>                                        <chr>         
## 1 5.51.01.10.gdp     Per capita GDP growth                        GDP per capit…
## 2 6.0.GDP_current    GDP (current $)                              GDP is the su…
## 3 6.0.GDP_growth     GDP growth (annual %)                        Annual percen…
## 4 6.0.GDP_usd        GDP (constant 2005 $)                        GDP is the su…
## 5 6.0.GDPpc_constant GDP per capita, PPP (constant 2011 internat… GDP per capit…
## 6 BG.GSR.NFSV.GD.ZS  Trade in services (% of GDP)                 Trade in serv…

Extract data for the indicator “6.0.GDP_current”

gdp_data <- wb_data("6.0.GDP_current")
head(gdp_data, 10)   # Show first 10 rows
## # A tibble: 10 × 9
##    iso2c iso3c country    date `6.0.GDP_current` unit  obs_status footnote
##    <chr> <chr> <chr>     <dbl>             <dbl> <chr> <chr>      <chr>   
##  1 AR    ARG   Argentina  2000     284203750000  <NA>  <NA>       <NA>    
##  2 AR    ARG   Argentina  2001     268696750000  <NA>  <NA>       <NA>    
##  3 AR    ARG   Argentina  2002      97724513456. <NA>  <NA>       <NA>    
##  4 AR    ARG   Argentina  2003     127586251761. <NA>  <NA>       <NA>    
##  5 AR    ARG   Argentina  2004     181873056797. <NA>  <NA>       <NA>    
##  6 AR    ARG   Argentina  2005     220813784300. <NA>  <NA>       <NA>    
##  7 AR    ARG   Argentina  2006     262666517347. <NA>  <NA>       <NA>    
##  8 AR    ARG   Argentina  2007     329317513143. <NA>  <NA>       <NA>    
##  9 AR    ARG   Argentina  2008     403781994528. <NA>  <NA>       <NA>    
## 10 AR    ARG   Argentina  2009     376627876888. <NA>  <NA>       <NA>    
## # ℹ 1 more variable: last_updated <date>

Extract the population (total) and GDP (current US$) for US and Norway

pop_gdp <- wb_data(indicator = c("SP.POP.TOTL", "NY.GDP.MKTP.CD"), 
                   country = c("US", "NO"), 
                   start_date = 2020, end_date = 2024)
pop_gdp
## # A tibble: 10 × 6
##    iso2c iso3c country        date NY.GDP.MKTP.CD SP.POP.TOTL
##    <chr> <chr> <chr>         <dbl>          <dbl>       <dbl>
##  1 NO    NOR   Norway         2020        3.68e11     5379475
##  2 NO    NOR   Norway         2021        5.03e11     5408320
##  3 NO    NOR   Norway         2022        5.96e11     5457127
##  4 NO    NOR   Norway         2023        4.83e11     5519594
##  5 NO    NOR   Norway         2024        4.84e11     5572272
##  6 US    USA   United States  2020        2.14e13   331577720
##  7 US    USA   United States  2021        2.37e13   332099760
##  8 US    USA   United States  2022        2.60e13   334017321
##  9 US    USA   United States  2023        2.77e13   336806231
## 10 US    USA   United States  2024        2.92e13   340110988

(B) Yahoo Finance, FRED & OANDA - quantmod

Yahoo Finance: Get stock data

# Download NVDA and TSLA stock prices
getSymbols(c("NVDA", "TSLA"), source = "yahoo")
## [1] "NVDA" "TSLA"
# Show last 10 rows of NVDA stock data
tail(NVDA, 10)
##            NVDA.Open NVDA.High NVDA.Low NVDA.Close NVDA.Volume NVDA.Adjusted
## 2025-09-08    167.55    170.96   167.35     168.31   163769100      168.3005
## 2025-09-09    169.09    170.98   166.74     170.76   157548400      170.7504
## 2025-09-10    176.64    179.29   175.47     177.33   226852000      177.3200
## 2025-09-11    179.68    180.28   176.48     177.17   151159300      177.1700
## 2025-09-12    177.77    178.60   176.45     177.82   124911000      177.8200
## 2025-09-15    175.67    178.85   174.51     177.75   147061600      177.7500
## 2025-09-16    177.00    177.50   174.38     174.88   140737800      174.8800
## 2025-09-17    172.64    173.20   168.41     170.29   211843800      170.2900
## 2025-09-18    173.98    177.10   172.96     176.24   191763300      176.2400
## 2025-09-19    175.77    178.08   175.18     176.67   236658800      176.6700

FRED data pull

# Inflation, consumer prices for USA/China/Egypt
getSymbols(c("FPCPITOTLZGCHN","FPCPITOTLZGEGY","FPCPITOTLZGUSA"), src="FRED")
## [1] "FPCPITOTLZGCHN" "FPCPITOTLZGEGY" "FPCPITOTLZGUSA"
# Show last few rows of US inflation data
tail(FPCPITOTLZGUSA)
##            FPCPITOTLZGUSA
## 2019-01-01       1.812210
## 2020-01-01       1.233584
## 2021-01-01       4.697859
## 2022-01-01       8.002800
## 2023-01-01       4.116338
## 2024-01-01       2.949525

(C) Foodbank - httr, jsonlite

Create a GET response to call the API

# Create GET request
foodbank <- httr::GET("https://www.givefood.org.uk/api/2/foodbanks/")

# View API GET response result
str(foodbank)
## List of 10
##  $ url        : chr "https://www.givefood.org.uk/api/2/foodbanks/"
##  $ status_code: int 403
##  $ headers    :List of 22
##   ..$ date                        : chr "Mon, 22 Sep 2025 22:06:06 GMT"
##   ..$ content-type                : chr "text/html; charset=UTF-8"
##   ..$ accept-ch                   : chr "Sec-CH-UA-Bitness, Sec-CH-UA-Arch, Sec-CH-UA-Full-Version, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platfor"| __truncated__
##   ..$ cf-mitigated                : chr "challenge"
##   ..$ critical-ch                 : chr "Sec-CH-UA-Bitness, Sec-CH-UA-Arch, Sec-CH-UA-Full-Version, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platfor"| __truncated__
##   ..$ cross-origin-embedder-policy: chr "require-corp"
##   ..$ cross-origin-opener-policy  : chr "same-origin"
##   ..$ cross-origin-resource-policy: chr "same-origin"
##   ..$ origin-agent-cluster        : chr "?1"
##   ..$ permissions-policy          : chr "accelerometer=(),autoplay=(),browsing-topics=(),camera=(),clipboard-read=(),clipboard-write=(),geolocation=(),g"| __truncated__
##   ..$ referrer-policy             : chr "same-origin"
##   ..$ server-timing               : chr "chlray;desc=\"98351b882d0ec475\""
##   ..$ x-content-type-options      : chr "nosniff"
##   ..$ x-frame-options             : chr "SAMEORIGIN"
##   ..$ cache-control               : chr "private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
##   ..$ expires                     : chr "Thu, 01 Jan 1970 00:00:01 GMT"
##   ..$ vary                        : chr "Accept-Encoding"
##   ..$ speculation-rules           : chr "\"/cdn-cgi/speculation\""
##   ..$ server                      : chr "cloudflare"
##   ..$ cf-ray                      : chr "98351b882d0ec475-EWR"
##   ..$ content-encoding            : chr "gzip"
##   ..$ alt-svc                     : chr "h3=\":443\"; ma=86400"
##   ..- attr(*, "class")= chr [1:2] "insensitive" "list"
##  $ all_headers:List of 1
##   ..$ :List of 3
##   .. ..$ status : int 403
##   .. ..$ version: chr "HTTP/2"
##   .. ..$ headers:List of 22
##   .. .. ..$ date                        : chr "Mon, 22 Sep 2025 22:06:06 GMT"
##   .. .. ..$ content-type                : chr "text/html; charset=UTF-8"
##   .. .. ..$ accept-ch                   : chr "Sec-CH-UA-Bitness, Sec-CH-UA-Arch, Sec-CH-UA-Full-Version, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platfor"| __truncated__
##   .. .. ..$ cf-mitigated                : chr "challenge"
##   .. .. ..$ critical-ch                 : chr "Sec-CH-UA-Bitness, Sec-CH-UA-Arch, Sec-CH-UA-Full-Version, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platfor"| __truncated__
##   .. .. ..$ cross-origin-embedder-policy: chr "require-corp"
##   .. .. ..$ cross-origin-opener-policy  : chr "same-origin"
##   .. .. ..$ cross-origin-resource-policy: chr "same-origin"
##   .. .. ..$ origin-agent-cluster        : chr "?1"
##   .. .. ..$ permissions-policy          : chr "accelerometer=(),autoplay=(),browsing-topics=(),camera=(),clipboard-read=(),clipboard-write=(),geolocation=(),g"| __truncated__
##   .. .. ..$ referrer-policy             : chr "same-origin"
##   .. .. ..$ server-timing               : chr "chlray;desc=\"98351b882d0ec475\""
##   .. .. ..$ x-content-type-options      : chr "nosniff"
##   .. .. ..$ x-frame-options             : chr "SAMEORIGIN"
##   .. .. ..$ cache-control               : chr "private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
##   .. .. ..$ expires                     : chr "Thu, 01 Jan 1970 00:00:01 GMT"
##   .. .. ..$ vary                        : chr "Accept-Encoding"
##   .. .. ..$ speculation-rules           : chr "\"/cdn-cgi/speculation\""
##   .. .. ..$ server                      : chr "cloudflare"
##   .. .. ..$ cf-ray                      : chr "98351b882d0ec475-EWR"
##   .. .. ..$ content-encoding            : chr "gzip"
##   .. .. ..$ alt-svc                     : chr "h3=\":443\"; ma=86400"
##   .. .. ..- attr(*, "class")= chr [1:2] "insensitive" "list"
##  $ cookies    :'data.frame': 0 obs. of  7 variables:
##   ..$ domain    : logi(0) 
##   ..$ flag      : logi(0) 
##   ..$ path      : logi(0) 
##   ..$ secure    : logi(0) 
##   ..$ expiration: 'POSIXct' num(0) 
##   ..$ name      : logi(0) 
##   ..$ value     : logi(0) 
##  $ content    : raw [1:7021] 3c 21 44 4f ...
##  $ date       : POSIXct[1:1], format: "2025-09-22 22:06:06"
##  $ times      : Named num [1:6] 0 0.000738 0.013335 0.032612 0.073649 ...
##   ..- attr(*, "names")= chr [1:6] "redirect" "namelookup" "connect" "pretransfer" ...
##  $ request    :List of 7
##   ..$ method    : chr "GET"
##   ..$ url       : chr "https://www.givefood.org.uk/api/2/foodbanks/"
##   ..$ headers   : Named chr "application/json, text/xml, application/xml, */*"
##   .. ..- attr(*, "names")= chr "Accept"
##   ..$ fields    : NULL
##   ..$ options   :List of 2
##   .. ..$ useragent: chr "libcurl/8.11.1 r-curl/6.2.0 httr/1.4.7"
##   .. ..$ httpget  : logi TRUE
##   ..$ auth_token: NULL
##   ..$ output    : list()
##   .. ..- attr(*, "class")= chr [1:2] "write_memory" "write_function"
##   ..- attr(*, "class")= chr "request"
##  $ handle     :Class 'curl_handle' <externalptr> 
##  - attr(*, "class")= chr "response"
# View the main source of the data needed (normally content)
str(foodbank$content)
##  raw [1:7021] 3c 21 44 4f ...

Convert the raw content to text (JSON string)

foodbankcontent <- httr::content(foodbank, as="text")

## No encoding supplied: defaulting to UTF-8.
str(foodbankcontent)
##  chr "<!DOCTYPE html><html lang=\"en-US\"><head><title>Just a moment...</title><meta http-equiv=\"Content-Type\" cont"| __truncated__
##  chr "[\n  {\n    \"name\": \"Littlehampton & District Food Bank\",\n    \"alt_name\": null,\n    \"slug\": \"littleh"| __truncated__

Convert the JSON string to a dataframe and view as a table

# Load required packages
pacman::p_load(httr, jsonlite)

# Correct API URL (JSON endpoint for foodbanks)
url <- "https://www.givefood.org.uk/api/2/foodbanks/"

# Send GET request
foodbank <- httr::GET(url)

# Check the status code (200 means success)
status_code(foodbank)
## [1] 403
# If success, parse content as JSON
if (status_code(foodbank) == 200) {
  foodbankcontent <- httr::content(foodbank, as = "text", encoding = "UTF-8")
  foodbankJSON <- jsonlite::fromJSON(foodbankcontent, flatten = TRUE)
  head(foodbankJSON)
} else {
  print("API request failed. Check the URL or internet connection.")
}
## [1] "API request failed. Check the URL or internet connection."
#{r #setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)

# Load necessary packages
if (!require(knitr)) install.packages("knitr")
## Loading required package: knitr
library(knitr)
answers <- data.frame(
  Question = 1:10,
  Answer = c(
    "True",    # Q1 - API benefits
    "False",   # Q2 - Don't need to re-install packages
    "True",    # Q3 - Must load library
    "A, B, C, D",  # Q4 - All sources valid
    "True",    # Q5 - getSymbols sources
    "F",       # Q6 - Only correct format & range
    "86",      # Q7 - Total trading days
    "D",       # Q8 - Highest Open during Dec 9–18
    "True",    # Q9 - DataCamp completion
    "True"     # Q10 - API extraction commitment
  ),
  Explanation = c(
    "APIs allow control over data exposure & rate limiting.",
    "install.packages() is only needed once, not every session.",
    "library() is required each session to access package functions.",
    "All methods provide documentation or usage examples.",
    "getSymbols supports multiple sources like Yahoo, FRED, CSV, etc.",
    "getSymbols('MSFT', ..., to = '2025-01-31') is the exact match.",
    "MSFT has 86 trading days between Oct 1 and Jan 31.",
    "Highest open price occurred in Dec 9–18 period.",
    "DataCamp R course completion or commitment is acknowledged.",
    "Student is prepared to show custom API use not covered in class."
  )
)

kable(answers, caption = "Quiz Answer Key with Justifications", align = "c")
Quiz Answer Key with Justifications
Question Answer Explanation
1 True APIs allow control over data exposure & rate limiting.
2 False install.packages() is only needed once, not every session.
3 True library() is required each session to access package functions.
4 A, B, C, D All methods provide documentation or usage examples.
5 True getSymbols supports multiple sources like Yahoo, FRED, CSV, etc.
6 F getSymbols(‘MSFT’, …, to = ‘2025-01-31’) is the exact match.
7 86 MSFT has 86 trading days between Oct 1 and Jan 31.
8 D Highest open price occurred in Dec 9–18 period.
9 True DataCamp R course completion or commitment is acknowledged.
10 True Student is prepared to show custom API use not covered in class.