R
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Data Structures
-
Section 4: Data Manipulation
-
Section 5: Visualization and Statistics
-
Section 6: Advanced R
-
Section 7: Practical Projects
-
Section 8: Interview Practice
-
Section 9: More Practice Exercises
-
Section 10: Shiny Apps in Depth
-
Section 11: More Data Wrangling
-
Section 12: Tidyverse Deep Dive
-
Section 13: Statistical Modeling Deep Dive
-
Section 14: Machine Learning in R
-
Section 15: R Visualization Deep Dive
-
Section 16: R Package Development Deep Dive
-
Section 17: R for Reproducible Research
-
Section 18: R and Databases
-
Section 19: R Performance Optimization
-
Section 20: Bioinformatics and Specialized R
-
Section 21: More Shiny Practice
-
Section 22: More Practice Exercises
-
Section 23: R Data Structures Deep Dive
-
Section 24: More Interview and Review
-
Section 25: R for Business Analytics
-
Section 26: R Text Mining and NLP
-
Section 27: R Spatial Data Analysis
-
Section 28: R Deep Learning
-
Section 29: Advanced Statistical Techniques
-
Section 30: R Object Systems Deep Dive
-
Section 31: R Environments and Metaprogramming
-
Section 32: R for Finance
-
Section 33: R for Clinical and Health Data
-
Section 34: More Shiny Advanced Practice
-
Section 35: R Data Cleaning Deep Dive
-
Section 36: R Reporting Automation
-
Section 37: More Practical Projects Round 2
-
Section 38: R Ecosystem and Career
-
Section 39: More Visualization Practice
-
Section 40: R for Experimentation
-
Section 41: R for Genomics and Bioinformatics Deep Dive
-
Section 42: R for Marketing Analytics
-
Section 43: R Data Import/Export Deep Dive
-
Section 44: R String Processing Deep Dive
-
Section 45: R for Actuarial and Insurance Analytics
-
Section 46: R Testing and Quality Assurance Deep Dive
-
Section 47: R Version Control and Collaboration
-
Section 48: R Advanced Functional Programming
-
Section 49: R for Supply Chain and Operations
-
Section 50: More Practice Exercises Round 3
-
Section 51: R Dashboards and BI Integration
-
Section 52: R Data Governance and Ethics
-
Section 53: More Modeling Practice
-
Section 54: R Final Capstone Projects
-
Section 55: R for Sports Analytics
-
Section 56: More Interview Practice Round 2
-
Section 57: R Networking and APIs
-
Section 58: R for Environmental Science
-
Section 59: R Notebook and Documentation Practices
-
Section 60: More Data Wrangling Mastery
-
Section 61: R for A/B Testing at Scale
-
Section 62: R Package Ecosystem Deep Dive
171: Working with JSON Data in R
Think of a JSON file like a set of nested Russian Matryoshka dolls. On the surface, you have one big doll (the root object). You open it up, and inside you find a few smaller dolls (key-value pairs). Some of those smaller dolls, when opened, reveal even more dolls inside them (nested lists or objects). It's a hierarchy. The trick with JSON in R is that R prefers its data in flat, rectangular spreadsheets—data frames—while JSON is more like a branching tree.
When we map this to R, the "big doll" becomes a named list. The "labels" on the dolls become the names of the list elements, and the "items inside" become the values. If you have a list of similar items (like a list of employees in a company), R can often "flatten" those into a data frame for you, provided the structure is consistent. I've spent a lot of time cleaning up API responses, and I can tell you that the biggest headache isn't the syntax—it's understanding exactly how deep those dolls are nested before you try to pull data out.
Bringing the Outside World In with jsonlite
In the R ecosystem, jsonlite is the heavy lifter. You might see other packages, but this is the one I use in production. The core function you'll live in is fromJSON(). It handles the translation from that JSON string into something R can actually manipulate.
Let's look at a real scenario. Imagine you're pulling data from a movie database API. The response doesn't just give you a table; it gives you a structured object:
library(jsonlite)
# Imagine this string came from an API call via httr or curl
movie_json <- '{
"title": "Interstellar",
"release_year": 2014,
"director": "Christopher Nolan",
"cast": ["Matthew McConaughey", "Anne Hathaway", "Jessica Chastain"],
"stats": {
"runtime": 169,
"rating": 8.6
}
}'
# Parse the JSON string into an R object
movie_data <- fromJSON(movie_json)
# Accessing the data
print(movie_data$title) # "Interstellar"
print(movie_data$cast[1]) # "Matthew McConaughey"
print(movie_data$stats$rating) # 8.6
Notice how jsonlite automatically decided that cast should be a character vector and stats should be another named list. It does a great job of guessing the types, but you always want to check the structure using str(movie_data) after a parse. Trust me, I've wasted hours trying to treat a list as a vector because I didn't check the structure first.
Flattening the Nest
The real power of jsonlite comes when you have a JSON array—basically a list of objects. If every object in that array has the same fields, fromJSON() will automatically simplify it into a data frame. This is the "magic" that makes R and JSON actually get along.
# A JSON array of movies
movies_json <- '[
{"title": "The Matrix", "year": 1999, "genre": "Sci-Fi"},
{"title": "Inception", "year": 2010, "genre": "Sci-Fi"},
{"title": "The Godfather", "year": 1972, "genre": "Crime"}
]'
# This automatically becomes a data frame
movies_df <- fromJSON(movies_json)
# Now you can use standard R data frame operations
sci_fi_movies <- movies_df[movies_df$genre == "Sci-Fi", ]
If the JSON is deeply nested and you don't want to keep typing $stats$details$value, you can use the flatten = TRUE argument within fromJSON(). This attempts to collapse nested objects into a single level by creating names like stats.rating. It's a huge time-saver when dealing with complex API responses.
Sending Data Back Out
Eventually, you'll need to send your results back to a web server or save them for a JavaScript frontend. That's where toJSON() comes in. The most important thing here is the pretty = TRUE argument. Without it, R spits out a single, massive line of text that is impossible for a human to read. If you're debugging, always set pretty = TRUE.
# Let's take that data frame and turn it back into JSON
json_output <- toJSON(movies_df, pretty = TRUE)
cat(json_output)
One quick tip: if you're working with dates or special R objects, toJSON() might behave unexpectedly. Always verify the output of your JSON string before sending it to a production API, or you'll find yourself in a very long debugging session with a frontend developer who is wondering why your dates look like numbers.
📋 Practical Task
Parsing a Complex Weather API Response
You have received the following JSON string from a weather service. The data is nested: there is a top-level object containing a list of "forecasts," and each forecast contains a "temperature" object with "min" and "max" values.
weather_json <- '{
"city": "Seattle",
"country": "USA",
"forecasts": [
{"date": "2023-10-01", "temp": {"min": 10, "max": 15}, "condition": "Rain"},
{"date": "2023-10-02", "temp": {"min": 11, "max": 17}, "condition": "Cloudy"},
{"date": "2023-10-03", "temp": {"min": 9, "max": 14}, "condition": "Rain"}
]
}'
Your goal:
- Use
jsonlite::fromJSON()to parse this string. Use theflatten = TRUEargument to make the temperature data easier to access. - Extract the
forecastsportion into its own data frame. - Calculate the average
maxtemperature across all days in the forecast. - Print the final average to the console.
There are no comments for now.