Here is a little investigation ; from moi.
library(jsonlite)
library(rjson)
# a hand crafted input
myjson <- '{"row1": [{"colval1":3,"colval2":4}],
"row2": [{"colval1":4,"colval2":3}]}'
json_by_row <- jsonlite::fromJSON(myjson)
# smushed
as.data.frame(json_by_row)
#why ?
str(json_by_row)
#oh, its a list of dataframes; so lets vertically stack those frames
#unsmushed
(mydf <- do.call(rbind,json_by_row))
#note the implicit rownames
(my_df_better <- tibble::rownames_to_column(mydf))
# lets write it to json to compare
(j_lite <- jsonlite::toJSON(my_df_better))
(j_rjsn <- rjson::toJSON(my_df_better))
# we have two representations ... lets read them in by the two methods
# this makes 4 combinations ...
(from_j_lite_lite <- jsonlite::fromJSON(j_lite))
(from_j_lite_rjsn <- jsonlite::fromJSON(j_rjsn))
(from_j_rjsn_lite <- rjson::fromJSON(j_lite))
(from_j_rjsn_rjsn <- rjson::fromJSON(j_rjsn))
# can we again make each of these data.frames ?
#1
from_j_lite_lite # already is
#2
as.data.frame(from_j_lite_rjsn) # easy
#3
as.data.frame(from_j_rjsn_lite) # smushed so ...
as.data.frame(do.call(rbind,from_j_rjsn_lite)) # unsmushed
#3
as.data.frame(from_j_rjsn_rjsn) # easy