Working with HTML and JSON Data

Author

Zaina Hassan

Approach

For this assignment, my goal is to become more familiar with HTML and JSON file formats by manually creating two files containing the same book information, importing each into a separate R data frame, and comparing the results to determine whether the two data frames are identical.

I will use three books within the genres of mystery, horror, and dystopian fiction: The Silent Patient by Alex Michaelides, The Talisman by Stephen King and Peter Straub, and The Handmaid’s Tale by Margaret Atwood. For each book, I will record the title, author(s), publication year, publisher, and genre. I chose these books because they share similar dark themes while representing different subgenres. The Talisman also satisfies the requirement of including a book with multiple authors.

I will first manually create an HTML file containing the book information in a table, followed by a JSON file containing the same information in a structured format. I will make sure both files contain matching values and consistent column names to make comparisons easier.

Next, I will use the rvest package to extract the HTML table and the jsonlite package to import the JSON data into R. I will examine the structure of both data frames and use the identical() function to determine whether they match in terms of values, column names, data types, and row order.

Finally, I will summarize the comparison results and discuss any differences or challenges encountered when working with the two file formats.

Load Required Packages

#Load packages
library(rvest)     # Read and extract HTML tables
library(jsonlite)  # Read and convert JSON data
library(dplyr)     # Data manipulation and comparison

Import HTML Data

# Public GitHub URL for HTML file
html_url <- "https://raw.githubusercontent.com/zxinah/DATA-607-Data-Acquisition-Management-/main/Week%207/books.html"

# Read the HTML file
html_page <- read_html(html_url)

# Extract the first HTML table
html_books <- html_page |>
  html_element("table") |>
  html_table()

# Convert to a data frame
html_books <- as.data.frame(html_books)

# Display data and structure
print(html_books)
                Title                    Authors Publication_Year
1  The Silent Patient           Alex Michaelides             2019
2        The Talisman Stephen King; Peter Straub             1984
3 The Handmaid's Tale            Margaret Atwood             1985
             Publisher                  Genre
1        Celadon Books Psychological thriller
2         Viking Press  Dark fantasy / horror
3 McClelland & Stewart      Dystopian fiction
str(html_books)
'data.frame':   3 obs. of  5 variables:
 $ Title           : chr  "The Silent Patient" "The Talisman" "The Handmaid's Tale"
 $ Authors         : chr  "Alex Michaelides" "Stephen King; Peter Straub" "Margaret Atwood"
 $ Publication_Year: int  2019 1984 1985
 $ Publisher       : chr  "Celadon Books" "Viking Press" "McClelland & Stewart"
 $ Genre           : chr  "Psychological thriller" "Dark fantasy / horror" "Dystopian fiction"

Import JSON Data

# Public GitHub URL for JSON file
json_url <- "https://raw.githubusercontent.com/zxinah/DATA-607-Data-Acquisition-Management-/main/Week%207/books.json"

# Read the JSON file
json_books <- fromJSON(json_url)

# Convert to a data frame
json_books <- as.data.frame(json_books)

# Display data and structure
print(json_books)
                Title                    Authors Publication_Year
1  The Silent Patient           Alex Michaelides             2019
2        The Talisman Stephen King; Peter Straub             1984
3 The Handmaid's Tale            Margaret Atwood             1985
             Publisher                  Genre
1        Celadon Books Psychological thriller
2         Viking Press  Dark fantasy / horror
3 McClelland & Stewart      Dystopian fiction
str(json_books)
'data.frame':   3 obs. of  5 variables:
 $ Title           : chr  "The Silent Patient" "The Talisman" "The Handmaid's Tale"
 $ Authors         : chr  "Alex Michaelides" "Stephen King; Peter Straub" "Margaret Atwood"
 $ Publication_Year: int  2019 1984 1985
 $ Publisher       : chr  "Celadon Books" "Viking Press" "McClelland & Stewart"
 $ Genre           : chr  "Psychological thriller" "Dark fantasy / horror" "Dystopian fiction"

Verify Comparison

# Compare dimensions
dim(html_books)
[1] 3 5
dim(json_books)
[1] 3 5
# Compare column names
identical(names(html_books), names(json_books))
[1] TRUE
# Compare data types
sapply(html_books, class)
           Title          Authors Publication_Year        Publisher 
     "character"      "character"        "integer"      "character" 
           Genre 
     "character" 
sapply(json_books, class)
           Title          Authors Publication_Year        Publisher 
     "character"      "character"        "integer"      "character" 
           Genre 
     "character" 
# Compare the entire data frames
identical(html_books, json_books)
[1] TRUE
# Final comparison result
if (identical(html_books, json_books)) {
  cat("Result: The HTML and JSON data frames are identical.")
} else {
  cat("Result: The HTML and JSON data frames are not identical.")
}
Result: The HTML and JSON data frames are identical.

Results

Both the HTML and JSON files were successfully imported into R and converted into separate data frames. Each data frame contained 3 observations and 5 variables: Title, Authors, Publication_Year, Publisher, and Genre.

Using the str() function, I confirmed that both data frames had matching column names and data types. The publication year was stored as an integer, while the remaining variables were stored as character values.

Finally, I used the identical() function to compare the two data frames, which returned TRUE. This confirms that the HTML and JSON files produced identical data frames, including their values, column names, data types, and structure.

Conclusion

This assignment helped me better understand how HTML and JSON store and organize the same information differently. HTML uses tables, rows, and cells to display structured data, while JSON uses objects and key value pairs to represent information.

Although the two file formats have different structures, I was able to import both into R using the rvest and jsonlite packages. The comparison confirmed that both formats produced identical data frames when the information was organized consistently.

One important takeaway was the importance of maintaining consistent column names, data types, and values when working with different data sources. This exercise also provided useful practice for working with web based data, which will be relevant when using web scraping and APIs in future assignments.