pachamaltese pachamaltese - 2 months ago 28
R Question

Convert JSON to data.frame with more than 2 columns

I am trying to properly convert a JSON to a data.frame with 3 columns.

This is a simplification of my data

# simplification of my real data
my_data <- '{"Bag 1": [["bananas", 1], ["oranges", 2]],"Bag 2": [["bananas", 3], ["oranges", 4], ["apples", 5]]}'

library(jsonlite)

my_data <- fromJSON(my_data)

> my_data
$`Bag 1`
[,1] [,2]
[1,] "bananas" "1"
[2,] "oranges" "2"

$`Bag 2`
[,1] [,2]
[1,] "bananas" "3"
[2,] "oranges" "4"
[3,] "apples" "5"


I try to convert that to a data.frame

# this return an error about "arguments imply differing number of rows: 2, 3"
my_data <- as.data.frame(my_data)

> my_data <- as.data.frame(my_data)
Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, :
arguments imply differing number of rows: 2, 3


This is my solution to create the data.frame

# my solution
my_data <- data.frame(fruit = do.call(c, my_data),
bag_number = rep(1:length(my_data),
sapply(my_data, length)))

# how it looks
my_data

> my_data
fruit bag_number
Bag 11 bananas 1
Bag 12 oranges 1
Bag 13 1 1
Bag 14 2 1
Bag 21 bananas 2
Bag 22 oranges 2
Bag 23 apples 2
Bag 24 3 2
Bag 25 4 2
Bag 26 5 2


But my idea is to obtain something like this to avoid problems like doing
my_data[a:b,1]
when I want to use ggplot2 and others.

fruit | quantity | bag_number
oranges | 2 | 1
bananas | 1 | 1
oranges | 4 | 2
bananas | 3 | 2
apples | 5 | 2

Answer
library(plyr)

# import data (note that the rJSON package does this differently than the jsonlite package)
data.import <- jsonlite::fromJSON(my_data)

# combine all data using plyr
df <- ldply(data.mine, rbind)

# clean up column names
colnames(df) <- c('bag_number', 'fruit', 'quantity')

  bag_number   fruit quantity
1      Bag 1 bananas        1
2      Bag 1 oranges        2
3      Bag 2 bananas        3
4      Bag 2 oranges        4
5      Bag 2  apples        5
Comments