DATA 607-Assignment 9 – Using a New York Times API in R: CodeBase

Bikash Bhowmik —- 17-Oct-2026

Project Overview

The purpose of this assignment is to work with a public New York Times API using R. I will retrieve data through an API request, process the JSON response, and organize the information into a tidy data frame for analysis.

For this assignment, I selected the New York Times Most Popular API, which provides information about articles that receive the most views, shares, or emails during a specific period. I chose this API because it provides structured article information that can be easily processed and analyzed using R.

My main research question is:

Which sections of The New York Times have the most articles appearing on the most-viewed list during the past seven days?

API Overview and Request

I selected the New York Times Most Popular API, which provides information about the most-viewed articles over a specified period.

API Endpoint:

/svc/mostpopular/v2/viewed/7.json

API Base URL:

https://api.nytimes.com

Request Parameters:

  • period = 7: Retrieves articles from the seven-day most-viewed list.
  • api-key: Authenticates the API request.

The API returns article information in JSON format, including article titles, sections, publication dates, and other metadata.

An API key is required to access the data. For security, I will store my key in an environment variable and retrieve it in R using Sys.getenv("NYT_API_KEY") instead of including it directly in the code.

This approach protects the API key and allows the R code to be shared without exposing authentication credentials.

Loaded library
library(httr)
library(jsonlite)
library(tidyverse)
library(kableExtra)

Verify API Key in environment variable

api_key <- Sys.getenv("NYT_API_KEY")

if (api_key == "") {
  stop("NYT_API_KEY not found. Please store your API key in an environment variable.")
} else {
  cat("NYT API key found!")
}
NYT API key found!

Make API Request

base_url <- "https://api.nytimes.com/svc/mostpopular/v2/viewed/7.json"

response <- GET(
  url = base_url,
  query = list(`api-key` = api_key)
)

stop_for_status(response)

cat("NYT API request completed successfully!\n")
NYT API request completed successfully!
cat("HTTP Status Code:", status_code(response), "\n")
HTTP Status Code: 200 

Methodology

I plan to complete the assignment using the following steps:

  • Load R packages: Use httr, jsonlite, dplyr, and other tidyverse packages needed to retrieve and process the data.

  • Access the API key: Retrieve the stored API key using Sys.getenv(“NYT_API_KEY”).

  • Request data: Send a GET request to the New York Times Most Popular API.

  • Read the JSON response: Convert the returned JSON data into an R object.

  • Extract article information: Identify the results portion of the response, which contains the article records.

  • Create a tidy data frame: Convert the extracted information into a tibble.

  • Select useful variables: Keep columns such as article title, section, subsection, publication date, and article URL.

  • Analyze the results: Group articles by section and count how many articles appear in each category.

  • Present findings: Display a summary table showing which sections have the highest number of articles on the most-viewed list.

API Data Parse/Inspect/Transform

Parse JSON Response

nyt_text <- content(response, as = "text", encoding = "UTF-8")
nyt_json <- fromJSON(nyt_text, flatten = TRUE)

Inspect Response Structure

names(nyt_json)
[1] "status"      "copyright"   "num_results" "results"    
nyt_json$status
[1] "OK"
nyt_json$num_results
[1] 20

Convert Results to a Tidy Data Frame

nyt_df <- as_tibble(nyt_json$results) %>%
  select(
    url,
    section,
    subsection,
    byline,
    type,
    title,
    abstract,
    published_date,
    source,
    asset_id,
    updated,
    nytdsection,
    adx_keywords
  ) %>%
  mutate(
    published_date = as.Date(published_date),
    updated = as.POSIXct(updated, format = "%Y-%m-%d %H:%M:%S"),
    subsection = na_if(subsection, "")
  )

Data Inspection and Transformation

Inspecting Data

glimpse(nyt_df)
Rows: 20
Columns: 13
$ url            <chr> "https://www.nytimes.com/2026/10/27/world/americas/braz…
$ section        <chr> "World", "U.S.", "Opinion", "Polls", "Arts", "U.S.", "U…
$ subsection     <chr> "Americas", "Politics", NA, NA, "Television", "Politics…
$ byline         <chr> "By Ana Ionova, Edward Wong and Thayz Guimarães", "By D…
$ type           <chr> "Article", "Article", "Interactive", "Interactive", "Ar…
$ title          <chr> "Flávio Bolsonaro Flees Brazil for the U.S. After Elect…
$ abstract       <chr> "Officials in Argentina said Mr. Bolsonaro entered the …
$ published_date <date> 2026-10-27, 2026-10-23, 2026-10-26, 2026-09-10, 2026-1…
$ source         <chr> "New York Times", "New York Times", "New York Times", "…
$ asset_id       <dbl> 1e+14, 1e+14, 1e+14, 1e+14, 1e+14, 1e+14, 1e+14, 1e+14,…
$ updated        <dttm> 2026-10-28 08:24:08, 2026-10-24 09:50:35, 2026-10-26 1…
$ nytdsection    <chr> "world", "u.s.", "opinion", "polls", "arts", "u.s.", "u…
$ adx_keywords   <chr> "Politics and Government;Elections;Corruption (Institut…
section_counts <- nyt_df %>%
  count(section, sort = TRUE)

section_counts
# A tibble: 7 × 2
  section      n
  <chr>    <int>
1 U.S.        10
2 Opinion      5
3 Arts         1
4 New York     1
5 Polls        1
6 Well         1
7 World        1

Tidy Data Frame

Full dataset contains 20 records, below is showing 5 records

knitr::kable(
  head(nyt_df, 5),
  caption = "New York Times Most-Viewed Articles",
  format = "html",
  escape = TRUE
) %>%
  column_spec(1, width = "10em")
New York Times Most-Viewed Articles
url section subsection byline type title abstract published_date source asset_id updated nytdsection adx_keywords
https://www.nytimes.com/2026/10/27/world/americas/brazil-flavio-bolsonaro-flees-election.html World Americas By Ana Ionova, Edward Wong and Thayz Guimarães Article Flávio Bolsonaro Flees Brazil for the U.S. After Election Defeat Officials in Argentina said Mr. Bolsonaro entered the country by land then flew to Ecuador. Brazilian police had asked him to hand over his passports because of his links to an investigation. 2026-10-27 New York Times 1e+14 2026-10-28 08:24:08 world Politics and Government;Elections;Corruption (Institutional);Money Laundering;Ethics and Official Misconduct;United States International Relations;International Relations;Bolsonaro, Flavio;Bolsonaro, Jair (1955- );Da Silva, Luiz Inacio Lula;Trump, Donald J;Brazil;United States;Ecuador
https://www.nytimes.com/2026/10/23/us/politics/justice-dept-alaska-senate-race-sullivan.html U.S. Politics By Devlin Barrett and Kellen Browning Article On Trump’s Order, Justice Dept. Seeks to Block Alaska Vote if Republican Loses The department, in a highly unusual lawsuit, argued that confusion over candidates with similar names could taint the election result. 2026-10-23 New York Times 1e+14 2026-10-24 09:50:35 u.s. Elections, Senate;Names, Personal;Midterm Elections (2026);United States Politics and Government;Sullivan, Daniel Scott (1964- );Sullivan, Daniel J (1957- );Peltola, Mary;Trump, Donald J;Justice Department;Senate;Alaska
https://www.nytimes.com/interactive/2026/10/26/opinion/midterms-pollsters-pundits-scorecard-october.html Opinion NA Interactive The Midterms Are Next Week. Here’s Who We Think Will Win. It’s crunch time and still looking bullish for Democrats. 2026-10-26 New York Times 1e+14 2026-10-26 16:07:17 opinion internal-disable-fab;Polls and Public Opinion;Midterm Elections (2026);Hispanic-Americans;Voting and Voters;Elections, House of Representatives;Elections, Senate;Trump, Donald J;Paxton, Ken;Marshall, Roger W (1960- );Senate;House of Representatives;Democratic Party;Republican Party;Maine;Ohio;North Carolina;Kansas;Texas
https://www.nytimes.com/interactive/polls/latest-polls.html Polls NA Interactive Latest Polls Track all the polls from today, including the latest data on the 2026 midterm elections, governor’s races, President Trump’s approval rating and more. 2026-09-10 New York Times 1e+14 2026-10-30 10:57:47 polls Polls and Public Opinion;Midterm Elections (2026);internal-paywall-exempt;internal-disable-fab
https://www.nytimes.com/2026/10/29/arts/television/patrick-stewart-dead.html Arts Television By Anita Gates and William McDonald Article Patrick Stewart, Master of Shakespeare, ‘Star Trek’ and More, Has Died The British actor was 86. He achieved pop-culture stardom as Capt. Jean-Luc Picard on “Star Trek: The Next Generation.” 2026-10-29 New York Times 1e+14 2026-10-30 10:52:31 arts Deaths (Obituaries);Theater;Television;Movies;Actors and Actresses;internal-open-access-from-nl;Stewart, Patrick

Check Missing Values

nyt_df %>%
  summarise(
    missing_subsection = sum(is.na(subsection)),
    missing_byline = sum(is.na(byline)),
    missing_abstract = sum(is.na(abstract))
  )
# A tibble: 1 × 3
  missing_subsection missing_byline missing_abstract
               <int>          <int>            <int>
1                  9              0                0

The missing-value analysis found 9 missing values in the subsection column. The byline and abstract columns had no missing values. This indicates that the dataset is largely complete for these three variables.

Data Cleaning

Several data-cleaning steps were performed to prepare the New York Times API response for analysis.

  • API authentication: The API key was accessed through the NYT_API_KEY environment variable to avoid exposing sensitive credentials in the code.
  • JSON processing: The API response was converted into an R object, and the results component was extracted to obtain the article-level data.
  • Variable selection: Relevant fields, including article title, section, subsection, publication date, author information, and URL, were retained for analysis.
  • Data type conversion: The published_date variable was converted to R’s date format to support consistent date handling.
  • Missing value handling: Empty strings in the subsection column were replaced with NA so that missing information could be identified more easily.
  • Data simplification: Unnecessary nested information, such as multimedia metadata, was excluded to keep the dataset focused on the research question.

These steps produced a structured tibble that was easier to inspect, summarize, and visualize. The cleaned data was then used to count articles by section and identify which sections appeared most frequently in the API results.

Analysis: Articles by Section

Articles by Section

section_counts <- nyt_df %>%
  count(section, sort = TRUE)

section_counts
# A tibble: 7 × 2
  section      n
  <chr>    <int>
1 U.S.        10
2 Opinion      5
3 Arts         1
4 New York     1
5 Polls        1
6 Well         1
7 World        1

Top 7 Sections

top_7_sections <- section_counts %>%
  slice_head(n = 7)

knitr::kable(
  top_7_sections,
  col.names = c("NYT Section", "Number of Articles"),
  caption = "Top 7 New York Times Sections by Article Count",
  align = c("l", "c")
)
Top 7 New York Times Sections by Article Count
NYT Section Number of Articles
U.S. 10
Opinion 5
Arts 1
New York 1
Polls 1
Well 1
World 1

The table summarizes the seven sections represented in the New York Times Most Popular API results. The U.S. section ranked first with 10 articles, followed by Opinion with 5 articles. Arts, New York, Polls, Well, and World each contributed one article. These results show that the U.S. and Opinion sections together accounted for 75% of the 20 articles returned by the API, making them the most frequently represented sections in this dataset.

Visualization Interpretation

section_counts %>%
  ggplot(aes(x = reorder(section, n), y = n)) +
  geom_col(fill = "lightblue", color = "gray40", width = 0.7) +
  geom_text(aes(label = n), hjust = -0.3, size = 4) +
  coord_flip() +
  labs(
    title = "Most-Viewed New York Times Articles by Section",
    subtitle = "Distribution of articles returned by the API over the past seven days",
    x = "NYT Section",
    y = "Number of Articles"
  ) +
  expand_limits(y = max(section_counts$n) + 2) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    plot.subtitle = element_text(size = 10),
    axis.title = element_text(face = "bold"),
    panel.grid.major.y = element_blank()
  )

The bar chart shows the distribution of the 20 most-viewed New York Times articles across different sections. The U.S. section has the highest number of articles (10), followed by Opinion (5). The remaining sections—Arts, New York, Polls, Well, and World—each have one article. The visualization makes it easy to compare the sections and shows that U.S. news and Opinion together account for 75% of the articles in the dataset.

Results

The results show that the U.S. section had the highest number of articles on the New York Times most-viewed list, with 10 out of 20 articles (50%). The Opinion section ranked second with 5 articles (25%), while the remaining five sections each had one article (5%). This suggests that U.S. news and opinion articles received significant attention among readers. Overall, the findings indicate that these two sections dominated the most-viewed articles returned by the API during the seven-day period.

Conclusion

In this assignment, I used the New York Times Most Popular API to retrieve and analyze the most-viewed articles from the past seven days. Using R, I successfully retrieved the JSON data, converted it into a tidy data frame, cleaned the relevant variables, and summarized the number of articles by section.

The results showed that the U.S. section had the highest representation, with 10 out of 20 articles (50%), followed by the Opinion section with 5 articles (25%). The remaining sections each contributed one article. These findings suggest that U.S. news and opinion articles were particularly prominent among the most-viewed articles returned by the API.

Overall, this assignment helped me gain practical experience working with a public API, processing JSON data, and using R for data cleaning, analysis, and visualization. Although the analysis was limited to 20 articles from a single API request, it demonstrated how API data can be transformed into useful information for answering a research question.