Assignment 7 – Working with XML and JSON in R

Packages:

#install.packages("XML")
library(rvest)
library(xml2)
library(tibble)
library(jsonlite)

HTML df:

html_url <- "https://raw.githubusercontent.com/GuillermoCharlesSchneider/DATA-607/main/HW7/books.html"
#using rvest
html_df <- as.data.frame(read_html(html_url) %>% html_table(fill=TRUE)) 

XML df:

xml_url <- "https://raw.githubusercontent.com/GuillermoCharlesSchneider/DATA-607/main/HW7/books.xml"
#using xml2
xml_df <- read_xml(xml_url) 

#read through the nested elements and grab  the specified xpath
title <- xml_text(xml_find_all(xml_df, xpath = "//title"))
author <- xml_text(xml_find_all(xml_df, xpath = "//author"))
pages <- xml_text(xml_find_all(xml_df, xpath = "//pages"))
published <- xml_text(xml_find_all(xml_df, xpath = "//published"))

#recombine
xml_df <- tibble(title = title, author = author, pages = pages, published = published) %>% as.data.frame

JSON df:

json_url <- "https://raw.githubusercontent.com/GuillermoCharlesSchneider/DATA-607/main/HW7/books.json"
#using jsonlite
json_df <- fromJSON(json_url) %>% as.data.frame
## Warning: JSON string contains (illegal) UTF8 byte-order-mark!

Checking for differences:

all.equal(html_df, xml_df)
## [1] "Component \"pages\": Modes: numeric, character"                  
## [2] "Component \"pages\": target is numeric, current is character"    
## [3] "Component \"published\": Modes: numeric, character"              
## [4] "Component \"published\": target is numeric, current is character"
all.equal(xml_df, json_df)
## [1] TRUE
all.equal(json_df, html_df)
## [1] "Component \"pages\": Modes: character, numeric"                  
## [2] "Component \"pages\": target is character, current is numeric"    
## [3] "Component \"published\": Modes: character, numeric"              
## [4] "Component \"published\": target is character, current is numeric"
str(html_df)
## 'data.frame':    3 obs. of  4 variables:
##  $ title    : chr  "Dune" "The Truth" "A People's Future of the United States"
##  $ author   : chr  "Frank Herbert" "Terry Pratchett" "Charlie Jane Anders, Lesley Nneka Arimah and Charles Yu"
##  $ pages    : int  896 368 414
##  $ published: int  1965 2000 2019
str(xml_df)
## 'data.frame':    3 obs. of  4 variables:
##  $ title    : chr  "Dune" "The Truth" "A People's Future of the United States"
##  $ author   : chr  "Frank Herbert" "Terry Pratchett" "Charlie Jane Anders, Lesley Nneka Arimah and Charles Yu"
##  $ pages    : chr  "896" "368" "414"
##  $ published: chr  "1965" "2000" "2019"
str(json_df)
## 'data.frame':    3 obs. of  4 variables:
##  $ title    : chr  "Dune" "The Truth" "A People's Future of the United States"
##  $ author   : chr  "Frank Herbert" "Terry Pratchett" "Charlie Jane Anders, Lesley Nneka Arimah and Charles Yu"
##  $ pages    : chr  "896" "368" "414"
##  $ published: chr  "1965" "2000" "2019"

Changing xml and json dataframe columns, “pages” and “published”, to numeric rather than char:

xml_df$pages <- as.numeric(xml_df$pages)
xml_df$published <- as.numeric(xml_df$published)

json_df$pages <- as.numeric(json_df$pages)
json_df$published <- as.numeric(json_df$published)

Fixed! – html_df = xml_df = json_df

all.equal(html_df, xml_df)
## [1] TRUE
all.equal(xml_df, json_df)
## [1] TRUE
all.equal(json_df, html_df)
## [1] TRUE