Data 607 Assignment: HTML and JSON Data Formats

Author

David Melchor

Introduction

The objective of this assignment is to practice creating structured data files by hand and loading them into R for downstream analysis. We are using data focused on diabetes management, including titles, authors, publication years, publishers, and genres. At least one book in our dataset contains multiple authors to satisfy the assignment requirements.

Packages and Data Loading

For this assignment, we use packages designed for web scraping and data parsing to load our manually created files from GitHub.

# Loading packages
pacman::p_load(rvest, jsonlite, tidyverse, knitr, kableExtra)

Loading HTML Data

We start by loading the data from our manually created HTML file. We use the raw version of the GitHub URL so that the rvest package can read the table directly into R.

# Use the raw version of the GitHub URL
html_url <- "https://raw.githubusercontent.com/Dave-Melchor/Data-607-Data-Acquisition-and-Management/refs/heads/main/data/raw/books.html"

# Import HTML table directly into a data frame
html_data <- html_url |> 
  read_html() |> 
  html_table()

html_data <- html_data[[1]]

# Inspect the dataset
str(html_data)
tibble [3 × 5] (S3: tbl_df/tbl/data.frame)
 $ Title    : chr [1:3] "Think Like a Pancreas" "Sugar Surfing" "The Diabetes Code"
 $ Authors  : chr [1:3] "Gary Scheiner" "Stephen W Ponder and Kevin L McMahon" "Jason Fung"
 $ Year     : int [1:3] 2012 2015 2018
 $ Publisher: chr [1:3] "Da Capo Lifelong Books" "Gutenberg Publishing" "Greystone Books"
 $ Genre    : chr [1:3] "Health" "Health" "Health"
# Make summary table for HTML data
html_data |> 
  kbl(
    caption = "Table 1. Books Data Loaded from HTML",
    align = c("l", "l", "c", "l", "l")
  ) |> 
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  ) |> 
  column_spec(1, bold = TRUE)
Table 1. Books Data Loaded from HTML
Title Authors Year Publisher Genre
Think Like a Pancreas Gary Scheiner 2012 Da Capo Lifelong Books Health
Sugar Surfing Stephen W Ponder and Kevin L McMahon 2015 Gutenberg Publishing Health
The Diabetes Code Jason Fung 2018 Greystone Books Health

Loading JSON Data

Next, we load the same dataset from our manually created JSON file using the jsonlite package.

# Use the raw version of the GitHub URL
json_url <- "https://raw.githubusercontent.com/Dave-Melchor/Data-607-Data-Acquisition-and-Management/refs/heads/main/data/raw/books.json"

# Import JSON data directly into a data frame
json_data <- fromJSON(json_url)

# Inspect the dataset
str(json_data)
'data.frame':   3 obs. of  5 variables:
 $ Title    : chr  "Think Like a Pancreas" "Sugar Surfing" "The Diabetes Code"
 $ Authors  : chr  "Gary Scheiner" "Stephen W Ponder and Kevin L McMahon" "Jason Fung"
 $ Year     : int  2012 2015 2018
 $ Publisher: chr  "Da Capo Lifelong Books" "Gutenberg Publishing" "Greystone Books"
 $ Genre    : chr  "Health" "Health" "Health"
# Make summary table for JSON data
json_data |> 
  kbl(
    caption = "Table 2. Books Data Loaded from JSON",
    align = c("l", "l", "c", "l", "l")
  ) |> 
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed", "responsive"),
    full_width = FALSE,
    position = "center"
  ) |> 
  column_spec(1, bold = TRUE)
Table 2. Books Data Loaded from JSON
Title Authors Year Publisher Genre
Think Like a Pancreas Gary Scheiner 2012 Da Capo Lifelong Books Health
Sugar Surfing Stephen W Ponder and Kevin L McMahon 2015 Gutenberg Publishing Health
The Diabetes Code Jason Fung 2018 Greystone Books Health

Comparing Data Frames

The final step requires us to compare the two data frames to determine whether they are identical.

# Check if both data frames are identical
identical(html_data, json_data)
[1] FALSE

Conclusion

By manually creating both the HTML table and the JSON file, we can see how different file formats structure the same underlying information. While the data looks identical at a glance, checking them with identical() returns FALSE. This happens because html_table() reads all columns in as character strings by default, whereas jsonlite preserves numeric data types like integers.

Citation

Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (2023). R for Data Science (2nd ed.). O’Reilly Media. Chapter 24: Web Scraping (Section 24.3: HTML Basics). https://r4ds.hadley.nz/webscraping.html#html-basics