Week 7 Assignment | HTML and JSON

Approach

For this assignment, I will select three books related to data science and data analytics, including at least one book with multiple authors, as per instructions. For each book, I will include the title, authors, publication year, publisher, and ISBN. I will manually create an HTML file containing the information in a table and a JSON file containing the same information using key-value pairs. I will then use R to load each file into a separate data frame. Lastly, I will compare the two data frames to determine whether they are identical and identify any differences in their structure or data types.

Introduction

This assignment explores how HTML and JSON can store the same data in different formats. I selected three books related to data science and manually created an HTML and JSON file containing their title, authors, publication year, publisher, and ISBN. I will use R to load both files into data frames and compare the results.

library(rvest)
library(jsonlite)
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

Loading the HTML Data

First, I use the rvest package to read the HTML file. I then locate the table within the HTML document and convert it into an R data frame.

html_page <- read_html("books.html")

html_books <- html_page %>%
  html_element("table") %>%
  html_table()

html_books
# A tibble: 3 × 5
  Title                                          Authors  Year Publisher    ISBN
  <chr>                                          <chr>   <int> <chr>       <dbl>
1 R for Data Science, 2nd Edition                Hadley…  2023 O'Reilly… 9.78e12
2 Data Science for Business                      Foster…  2013 O'Reilly… 9.78e12
3 Practical Statistics for Data Scientists, 2nd… Peter …  2020 O'Reilly… 9.78e12

Loading the JSON Data

Next, I use the jsonlite package to read the manually created JSON file and convert it into a separate R data frame.

json_books <- fromJSON("books.json")

json_books
                                                  Title
1                       R for Data Science, 2nd Edition
2                             Data Science for Business
3 Practical Statistics for Data Scientists, 2nd Edition
                                                   Authors Year      Publisher
1 Hadley Wickham, Mine Çetinkaya-Rundel, Garrett Grolemund 2023 O'Reilly Media
2                              Foster Provost, Tom Fawcett 2013 O'Reilly Media
3                  Peter Bruce, Andrew Bruce, Peter Gedeck 2020 O'Reilly Media
           ISBN
1 9781492097396
2 9781449374273
3 9781492072935

Comparing the data frames

identical(html_books, json_books)
[1] FALSE
all.equal(html_books, json_books)
[1] "Attributes: < Component \"class\": Lengths (3, 1) differ (string compare on first 1) >"
[2] "Attributes: < Component \"class\": 1 string mismatch >"                                
[3] "Component \"ISBN\": Modes: numeric, character"                                         
[4] "Component \"ISBN\": target is numeric, current is character"                           

all.equal() provides more information about the differences.

str(html_books)
tibble [3 × 5] (S3: tbl_df/tbl/data.frame)
 $ Title    : chr [1:3] "R for Data Science, 2nd Edition" "Data Science for Business" "Practical Statistics for Data Scientists, 2nd Edition"
 $ Authors  : chr [1:3] "Hadley Wickham, Mine Çetinkaya-Rundel, Garrett Grolemund" "Foster Provost, Tom Fawcett" "Peter Bruce, Andrew Bruce, Peter Gedeck"
 $ Year     : int [1:3] 2023 2013 2020
 $ Publisher: chr [1:3] "O'Reilly Media" "O'Reilly Media" "O'Reilly Media"
 $ ISBN     : num [1:3] 9.78e+12 9.78e+12 9.78e+12
str(json_books)
'data.frame':   3 obs. of  5 variables:
 $ Title    : chr  "R for Data Science, 2nd Edition" "Data Science for Business" "Practical Statistics for Data Scientists, 2nd Edition"
 $ Authors  : chr  "Hadley Wickham, Mine Çetinkaya-Rundel, Garrett Grolemund" "Foster Provost, Tom Fawcett" "Peter Bruce, Andrew Bruce, Peter Gedeck"
 $ Year     : int  2023 2013 2020
 $ Publisher: chr  "O'Reilly Media" "O'Reilly Media" "O'Reilly Media"
 $ ISBN     : chr  "9781492097396" "9781449374273" "9781492072935"

Comparing the Data Frames

Before comparing the two data frames, I examined their structures. The HTML data imported the ISBN column as numeric, while the JSON data imported ISBN as character. The HTML data was also stored as a tibble, while the JSON data was stored as a standard data frame. I will first compare the original objects before standardizing these differences.

identical(html_books, json_books)
[1] FALSE
all.equal(html_books, json_books)
[1] "Attributes: < Component \"class\": Lengths (3, 1) differ (string compare on first 1) >"
[2] "Attributes: < Component \"class\": 1 string mismatch >"                                
[3] "Component \"ISBN\": Modes: numeric, character"                                         
[4] "Component \"ISBN\": target is numeric, current is character"                           

Standardizing the Data

The initial comparison returned FALSE because the HTML data was stored as a tibble while the JSON data was stored as a data frame. The ISBN column also had different data types. To make a fair comparison, I will convert both objects to standard data frames and store ISBN as character data.

html_books_clean <- html_books %>%
  as.data.frame() %>%
  mutate(ISBN = as.character(ISBN))

json_books_clean <- json_books %>%
  as.data.frame() %>%
  mutate(ISBN = as.character(ISBN))
str(html_books_clean)
'data.frame':   3 obs. of  5 variables:
 $ Title    : chr  "R for Data Science, 2nd Edition" "Data Science for Business" "Practical Statistics for Data Scientists, 2nd Edition"
 $ Authors  : chr  "Hadley Wickham, Mine Çetinkaya-Rundel, Garrett Grolemund" "Foster Provost, Tom Fawcett" "Peter Bruce, Andrew Bruce, Peter Gedeck"
 $ Year     : int  2023 2013 2020
 $ Publisher: chr  "O'Reilly Media" "O'Reilly Media" "O'Reilly Media"
 $ ISBN     : chr  "9781492097396" "9781449374273" "9781492072935"
str(json_books_clean)
'data.frame':   3 obs. of  5 variables:
 $ Title    : chr  "R for Data Science, 2nd Edition" "Data Science for Business" "Practical Statistics for Data Scientists, 2nd Edition"
 $ Authors  : chr  "Hadley Wickham, Mine Çetinkaya-Rundel, Garrett Grolemund" "Foster Provost, Tom Fawcett" "Peter Bruce, Andrew Bruce, Peter Gedeck"
 $ Year     : int  2023 2013 2020
 $ Publisher: chr  "O'Reilly Media" "O'Reilly Media" "O'Reilly Media"
 $ ISBN     : chr  "9781492097396" "9781449374273" "9781492072935"
identical(html_books_clean, json_books_clean)
[1] TRUE

Conclusion

The initial comparison returned FALSE because the HTML and JSON files imported with different object classes and ISBN data types. After converting both to standard data frames and storing ISBN as character data, the final comparison returned TRUE. This confirmed that both files contained the same book information despite being stored in different formats.