An API (Application Programming Interface) enables different software applications to communicate, exchange information, and interact with one another efficiently.
This assignment requires us to retrieve data from a specific New York Times API endpoint, which is a digital location where software applications can send requests to programmatically access information stored in a database. To access data from a New York Times API endpoint, it is necessary to create an account and obtain an API key from them. The API Key is a randomly generated, unique and secure code that authorizes a user to connect to the server and retrieve data.
In this assignment, I will load the New York Times Top Stories in Travel API list using my API key. Then, I will use the data to answer the following question: Which category in the top stories travel section is ranked highest?
Load necessary packages:
library (httr2)library(jsonlite)library(purrr)
Attaching package: 'purrr'
The following object is masked from 'package:jsonlite':
flatten
library(rlang)
Attaching package: 'rlang'
The following objects are masked from 'package:purrr':
flatten, flatten_chr, flatten_dbl, flatten_int, flatten_lgl,
flatten_raw, invoke, splice
The following objects are masked from 'package:jsonlite':
flatten, unbox
library(tibble)library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
library(cli)
Using an API key to access data
I stored my API key in the R system environment to prevent sharing it with the public. Before I begin any processing, I will load the API key, validate it and the connection to the endpoint.
#load API Key into Rnyt_key <-Sys.getenv("NYT_API_KEY")
As previously stated, the endpoint that I’ll be using for this assignment is Top Stories in Travel
# ==========================================# ENDPOINT 1: Top Stories API (e.g., Travel)# ==========================================# url from NYT developers portal for Top Stories travel_url <-paste0("https://api.nytimes.com/svc/topstories/v2/travel.json?api-key=", nyt_key)req <-request(travel_url) |>req_headers(Accept ="application/json",`User-Agent`="Data-607-week9-cchomework" ) |>req_url_query(`api-key`= nyt_key)req
This code chunk validates the connection and returns the status. A status of “200” indicates success; “401” means invalid API key; “403” means “Access forbidden”; “404” means Endpoint not found.
# Unnesting Data toptravel <-as.tibble(travel$results)
Warning: `as.tibble()` was deprecated in tibble 2.0.0.
ℹ Please use `as_tibble()` instead.
ℹ The signature and semantics have changed, see `?as_tibble`.
Our toptravel data frame contains 25 rows and 19 variables or columns,many of which are identified by the term “facet.” According to the New York Times (NYT) Developer’s website, facets are arrays of strings that contain descriptive subject terms or topical keywords assigned to articles by Times indexers and used for retrieval based on various criteria. This is for the standardization of its metadata.
There are four categories of “facet”:
des_facet: Descriptive subjects, concepts, and themes.
per_facet: Names of specific people mentioned (e.g., [“Soto, Juan”]).
org_facet: Organizations, companies, or institutions (e.g., [“Google LLC”]).
geo_facet: Geographic locations, countries, or cities (e.g., [“Paris (France)”]).
For this assignment, I will focus on the “des_facet” column to assist in answering my question.
title
1
2 Up in the Clouds With the Pope, It’s Still Commercial
3 Taipei Is One of the World’s Great Food Capitals. Here’s Where to Go.
4 After 28 Years Walking Across the Globe, He’s Almost Home
5 Hit the Road This Season With These Useful New Map Features
6 Is There a ‘Safest Seat’ in a Train Crash? Experts Say It’s Not So Simple.
7 Text Message Referencing a ‘Hijack’ Forces United Flight to Return to Vegas
8 An ‘Endless Cruise’ Goes Broke, Stranding Passengers
9 The Ocean ‘Was the Color of Chocolate.’ Mexico Declares War on Seaweed.
10 Holiday Travel Costs Are Soaring. 5 Ways to Save.
11 A Song in Your Heart and a Pillow Under Your Head: 5 Hotels for Music Lovers
12 Europe’s Toughest Trek? We Put a Notorious Corsican Hike to the Test.
13 How to Spend a Bookish Afternoon in Chinatown, the Lower East Side & the East Village
14 Why Tofu Is the Perfect Dessert Ingredient
15 6 Horse-Centered Retreats That Go Beyond Trail Rides
16 Airbnb Says Guests Shouldn’t Have to Do the Dishes Anymore
17 A New Art-Filled Hotel Adds to Cape Town’s Skyline
18 36 Hours in Kansas City, Mo.
19 Help! Why Won’t Travel Insurance Pay for My $17,500 Broken Leg?
20 America Mints a New National Park, Elevating an Arizonan ‘Sky Island’
21 Rugby Star Ilona Maher’s 5 Favorite Places in Burlington, Vt.
22 Driving Inn to Inn to Discover the Hidden Charm of the Baltics
23 Boeing’s Large 737 Max Jet Secures U.S. Approval
24 Heading to France? Amid Recent Unrest, Here’s What to Know.
25 How Do Airports Prepare for Disaster? With Fake Screams and Cloth Dummies.
section des_facet_1
1 admin <NA>
2 world Airlines and Airplanes
3 t-magazine Travel and Vacations
4 world internal-open-access-from-nl
5 technology iOS (Operating System)
6 world Spain Train Crash (October 28, 2026)
7 travel Aviation Accidents, Safety and Disasters
8 travel Cruises
9 world Seaweed
10 travel Budget Travel
11 travel Travel and Vacations
12 travel Hikes and Hiking
13 books internal-disable-fab
14 t-magazine Tofu
15 travel Travel and Vacations
16 travel Travel and Vacations
17 t-magazine Hotels and Travel Lodgings
18 travel Travel and Vacations
19 travel Travel and Vacations
20 travel National Parks, Monuments and Seashores
21 travel Travel and Vacations
22 travel Travel and Vacations
23 business Airlines and Airplanes
24 travel Travel and Vacations
25 travel Airlines and Airplanes
des_facet_2
1 <NA>
2 Travel and Vacations
3 Hotels and Travel Lodgings
4 Walking
5 Android (Operating System)
6 Railroad Accidents and Safety
7 Airlines and Airplanes
8 Oil (Petroleum) and Gasoline
9 Algae
10 Thanksgiving Day
11 Hotels and Travel Lodgings
12 Camps and Camping
13 Books and Literature
14 Desserts
15 Horses
16 Hotels and Travel Lodgings
17 <NA>
18 <NA>
19 Travel Insurance
20 <NA>
21 Rugby
22 Restaurants
23 Aviation Accidents, Safety and Disasters
24 Demonstrations, Protests and Riots
25 Airports
des_facet_3
1 <NA>
2 Popes
3 Restaurants
4 Travel and Vacations
5 Maps
6 Railroads
7 Text Messaging
8 Prices (Fares, Fees and Rates)
9 Beaches
10 Christmas
11 Country Music
12 Travel and Vacations
13 Shopping and Retail
14 Interior Design and Furnishings
15 Hotels and Travel Lodgings
16 Customer Relations
17 <NA>
18 <NA>
19 Content Type: Service
20 <NA>
21 Restaurants
22 Hotels and Travel Lodgings
23 Factories and Manufacturing
24 <NA>
25 Aviation Accidents, Safety and Disasters
des_facet_4
1 <NA>
2 <NA>
3 Shopping and Retail
4 Content Type: Personal Profile
5 iPhone
6 <NA>
7 Threats and Threatening Messages
8 Travel and Vacations
9 Travel and Vacations
10 Travel and Vacations
11 Pop and Rock Music
12 <NA>
13 Content Type: Service
14 Furniture
15 Yoga
16 Cleaning Services
17 <NA>
18 <NA>
19 <NA>
20 <NA>
21 Beaches
22 Road Trips
23 Regulation and Deregulation of Industry
24 <NA>
25 Fires and Firefighters
des_facet_5
1 <NA>
2 <NA>
3 Tea
4 Records and Achievements
5 Mobile Applications
6 <NA>
7 Hijacking
8 US and Israeli Attack on Iran (2026)
9 Politics and Government
10 Prices (Fares, Fees and Rates)
11 Culture (Arts)
12 <NA>
13 vis-design
14 Pearls
15 Post-Traumatic Stress Disorder
16 <NA>
17 <NA>
18 <NA>
19 <NA>
20 <NA>
21 Ice Cream and Frozen Desserts
22 <NA>
23 Boeing 737 Max Groundings and Safety Concerns (2019)
24 <NA>
25 Rescues
des_facet_6 des_facet_7
1 <NA> <NA>
2 <NA> <NA>
3 Hikes and Hiking <NA>
4 internal-eafs <NA>
5 Automobiles Travel and Vacations
6 <NA> <NA>
7 Flight Attendants <NA>
8 <NA> <NA>
9 vis-photo <NA>
10 Reservations (Airlines, Hotels, Etc.) Hotels and Travel Lodgings
11 Bars and Nightclubs Music
12 <NA> <NA>
13 Book Trade and Publishing <NA>
14 Jewels and Jewelry <NA>
15 Therapy and Rehabilitation Volunteers and Community Service
16 <NA> <NA>
17 <NA> <NA>
18 <NA> <NA>
19 <NA> <NA>
20 <NA> <NA>
21 Bars and Nightclubs Hikes and Hiking
22 <NA> <NA>
23 <NA> <NA>
24 <NA> <NA>
25 Emergency Medical Treatment Disasters and Emergencies
des_facet_8
1 <NA>
2 <NA>
3 <NA>
4 <NA>
5 Smartphones
6 <NA>
7 <NA>
8 <NA>
9 <NA>
10 Content Type: Service
11 <NA>
12 <NA>
13 <NA>
14 <NA>
15 <NA>
16 <NA>
17 <NA>
18 <NA>
19 <NA>
20 <NA>
21 <NA>
22 <NA>
23 <NA>
24 <NA>
25 Police
What does this mean?
We now have the “traveldf” data frame which contains the two original columns, title and section, plus the eight unnested “des_facet” columns labeled “des_facet_1, des_facet_2…des_facet_8). I searched NYT website for more detailed information on typical travel taxonomy layout, only to find that each”des_facet” column provides more granular information and multiple topic tags, all related to the original article.
A google.com query asking “what do the des_facet_1, des_facet_2,des_facet_3, des_facet_4… columns represent” as related to top travel stories” revealed the following:
• Core Identifier: Travel and Vacations almost always occupies des_facet_1 for every article in this section, serving as the top-level classification.
• Accommodations & Dining: Hotels and Motels, Resorts, Restaurants, Bars and Wine Bars found in des_facet_2.
• Modes of Transit: Cruises, Airlines and Airplanes, Walking and Hiking, Automobiles found in des_facet_3.
• Niche Styles: Ecotourism, Luxury Goods and Services, Budgets and Budgeting, Culture found in des_facet 4.
Answering the question
Therefore, to answer my original query, “Which category in the top stories travel section is ranked highest?” I decided to rank the results of des_facet_1 and then plot them.
library(ggplot2)# 1. Calculate frequencies and rank them from highest to lowestranked_primary_topics <- traveldf |>filter(!is.na(des_facet_1)) |># Filter out any missing/NAcount(des_facet_1, name ="article_count") |># group by the primary topic and count occurrencesarrange(desc(article_count))# 2. View the resulting ranked tableprint(ranked_primary_topics)
des_facet_1 article_count
1 Travel and Vacations 9
2 Airlines and Airplanes 3
3 Aviation Accidents, Safety and Disasters 1
4 Budget Travel 1
5 Cruises 1
6 Hikes and Hiking 1
7 Hotels and Travel Lodgings 1
8 National Parks, Monuments and Seashores 1
9 Seaweed 1
10 Spain Train Crash (October 28, 2026) 1
11 Tofu 1
12 iOS (Operating System) 1
13 internal-disable-fab 1
14 internal-open-access-from-nl 1
# Take the top 10 primary topics for a cleaner chartranked_primary_topics |>slice_max(article_count, n =10) |>ggplot(aes(x =reorder(des_facet_1, article_count), y = article_count)) +geom_col(fill ="steelblue") +coord_flip() +# Flips axes so long text categories are easy to readlabs(title ="Top Primary Themes in NYT Travel Stories",x ="Primary Topic (des_facet_1)",y ="Number of Articles" ) +theme_minimal()
Here we see that “Travel and Vacations” and “Hotels and Travel Lodging” dominate the ratings While the remaining topics are negligible. This is a very unimpressive graphic and not very useful.
Second time around
So let’s rephrase the question: “How will our data look if we count all secondary and tertiary elements, (i.e. include des_facets_2 through 8)? What can we glean from this?” To accomplish this I ranked the combined topics across all columns to get a more diverse look at the travel data.
# 1. Reshape, combine, and count frequenciesranked_combined_topics <- traveldf |>pivot_longer( # Pivot columns des_facet_1 through des_facet_4 into a single long columncols =starts_with("des_facet"),names_to ="facet_position", # Tracks if it was 1, 2, 3---8values_to ="topic",values_drop_na =TRUE# Drops empty/null tags automatically ) |>count(topic, name ="total_appearances") |>#group by topic name/calculate total occurancesarrange(desc(total_appearances))# 2. View the complete ranked listprint(ranked_combined_topics)
# A tibble: 80 × 2
topic total_appearances
<chr> <int>
1 Travel and Vacations 16
2 Hotels and Travel Lodgings 7
3 Airlines and Airplanes 4
4 Aviation Accidents, Safety and Disasters 3
5 Content Type: Service 3
6 Hikes and Hiking 3
7 Restaurants 3
8 Bars and Nightclubs 2
9 Beaches 2
10 Prices (Fares, Fees and Rates) 2
# ℹ 70 more rows
Plotting new results
ranked_combined_topics |>slice_head(n =15) |># slice_head to get exactly the top 15 rows without breaking on ties# Plot, ensuring the items are reordered strictly by their total countggplot(aes(x =reorder(topic, total_appearances), y = total_appearances)) +geom_col(fill ="purple", width =0.8) +coord_flip() +labs(title ="Most Frequent Overall Topics in NYT Travel Stories",subtitle ="Combined count across des_facet_1 through des_facet_8",x =NULL, y ="Total Times Tagged" ) +theme_minimal(base_size =10) +theme(panel.grid.major.y =element_blank(), plot.title =element_text(face ="bold") )
Conclusion
This is a better visualization of the data culled from the NYT Top Travel Stories API, and helps answer my second question, How will our data look if we count all secondary and tertiary elements, (i.e. include des_facets_2 through 8)? What can we glean from this?
ANS: Even though “Travel and Vacations” and “Hotels and Travel Lodging” still dominate the ratings, a user can readily see a count of other top travel related articles that could be of interest to them. For instance, if their passion is hiking, there are three articles that may interest them; if their looking for restaurants while traveling, there are also three articles that they could read that may answer their questions.
Adding reproducibility of metadata.
The last step in our analysis is to save the reproducibility of the data.1
Since data is ever-changing, it’s important to memorialize the date/time of the data pull that is the basis of this analysis.
# Use UTC so each timestamp has one unambiguous time zone.retrieved_at <-format(Sys.time(), tz ="UTC", usetz =TRUE)travel_snapshot <- toptravel |>mutate(retrieved_at = retrieved_at,request_url = travel_url,.before =1 )travel_snapshot