I have some JSON data I've pulled in using jsonlite::fromJSON()
:
raw.content <- jsonlite::fromJSON("https://raw.githubusercontent.com/danwild/leaflet-velocity/master/demo/wind-gbr.json")
the structure of which ends up being:
> str(raw.content)
'data.frame': 2 obs. of 2 variables:
$ header:'data.frame': 2 obs. of 13 variables:
..$ parameterUnit : chr "m.s-1" "m.s-1"
..$ parameterNumber : int 2 3
..$ dx : num 1 1
..$ dy : num 1 1
..$ parameterNumberName: chr "eastward_wind" "northward_wind"
..$ la1 : num -7.5 -7.5
..$ la2 : num -28.5 -28.5
..$ parameterCategory : int 2 2
..$ lo2 : num 156 156
..$ nx : int 14 14
..$ ny : int 22 22
..$ refTime : chr "2017-02-01 23:00:00" "2017-02-01 23:00:00"
..$ lo1 : num 143 143
$ data :List of 2
..$ : num 0 0 0 0 0 0 0 0 0 0 ...
..$ : num 0 0 0 0 0 0 0 0 0 0 ...
I need to be able to turn some data back into this format so that I can use jsonlite::toJSON()
to get it back into the same JSON format is the example data above.
The problem: I've never seen this data structure before. It's a data.frame contain 2 obs of 2 vars, where the first is a data.frame and the second is a list. Other than a data frame containing a nested list (which the header does not seem to be), how does a data frame contain a data frame?
The data I have is in standard tibble (or data.frame) format, so I need to get from that back to that data structure. Using the example data above to start with tibbles, what I've tried (among many, many others:
data <- raw.content$data
header <- raw.content$header
> str(data.frame(header, data))
'data.frame': 308 obs. of 15 variables:
$ parameterUnit : chr "m.s-1" "m.s-1" "m.s-1" "m.s-1" ...
$ parameterNumber : int 2 3 2 3 2 3 2 3 2 3 ...
$ dx : num 1 1 1 1 1 1 1 1 1 1 ...
$ dy : num 1 1 1 1 1 1 1 1 1 1 ...
$ parameterNumberName : chr "eastward_wind" "northward_wind" "eastward_wind" "northward_wind" ...
$ la1 : num -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 ...
$ la2 : num -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 ...
$ parameterCategory : int 2 2 2 2 2 2 2 2 2 2 ...
$ lo2 : num 156 156 156 156 156 156 156 156 156 156 ...
$ nx : int 14 14 14 14 14 14 14 14 14 14 ...
$ ny : int 22 22 22 22 22 22 22 22 22 22 ...
$ refTime : chr "2017-02-01 23:00:00" "2017-02-01 23:00:00" "2017-02-01 23:00:00" "2017-02-01 23:00:00" ...
$ lo1 : num 143 143 143 143 143 143 143 143 143 143 ...
$ c.0..0..0..0..0..0..0..0..0..0..0..0..0..0..0..4.17000007629395.. : num 0 0 0 0 0 0 0 0 0 0 ...
$ c.0..0..0..0..0..0..0..0..0..0..0..0..0..0..0...3.88000011444092..: num 0 0 0 0 0 0 0 0 0 0 ...
Warning message:
In data.frame(header, data) :
row names were found from a short variable and have been discarded
data.x <- data[[1]]
data.y <- data[[2]]
newdata <- vector(mode = "list", length = 2)
newdata[[1]] <- data.x
newdata[[2]] <- data.y
> str(data.frame(header, newdata))
'data.frame': 308 obs. of 15 variables:
$ parameterUnit : chr "m.s-1" "m.s-1" "m.s-1" "m.s-1" ...
$ parameterNumber : int 2 3 2 3 2 3 2 3 2 3 ...
$ dx : num 1 1 1 1 1 1 1 1 1 1 ...
$ dy : num 1 1 1 1 1 1 1 1 1 1 ...
$ parameterNumberName : chr "eastward_wind" "northward_wind" "eastward_wind" "northward_wind" ...
$ la1 : num -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 -7.5 ...
$ la2 : num -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 -28.5 ...
$ parameterCategory : int 2 2 2 2 2 2 2 2 2 2 ...
$ lo2 : num 156 156 156 156 156 156 156 156 156 156 ...
$ nx : int 14 14 14 14 14 14 14 14 14 14 ...
$ ny : int 22 22 22 22 22 22 22 22 22 22 ...
$ refTime : chr "2017-02-01 23:00:00" "2017-02-01 23:00:00" "2017-02-01 23:00:00" "2017-02-01 23:00:00" ...
$ lo1 : num 143 143 143 143 143 143 143 143 143 143 ...
$ c.0..0..0..0..0..0..0..0..0..0..0..0..0..0..0..4.17000007629395.. : num 0 0 0 0 0 0 0 0 0 0 ...
$ c.0..0..0..0..0..0..0..0..0..0..0..0..0..0..0...3.88000011444092..: num 0 0 0 0 0 0 0 0 0 0 ...
Warning message:
In data.frame(header, newdata) :
row names were found from a short variable and have been discarded
As you can see both of these produce a single data frame, rather than a data frame containing a data frame and a list.
CodePudding user response:
You can put both items in a list then set the attributes manually:
header <- raw.content$header
data <- raw.content$data
result <- list(header, data)
attributes(result) <- list(names = c("header", "data"),
class = "data.frame",
row.names = 1:2)
str(result)
#> 'data.frame': 2 obs. of 2 variables:
#> $ header:'data.frame': 2 obs. of 13 variables:
#> ..$ parameterUnit : chr "m.s-1" "m.s-1"
#> ..$ parameterNumber : int 2 3
#> ..$ dx : num 1 1
#> ..$ dy : num 1 1
#> ..$ parameterNumberName: chr "eastward_wind" "northward_wind"
#> ..$ la1 : num -7.5 -7.5
#> ..$ la2 : num -28.5 -28.5
#> ..$ parameterCategory : int 2 2
#> ..$ lo2 : num 156 156
#> ..$ nx : int 14 14
#> ..$ ny : int 22 22
#> ..$ refTime : chr "2017-02-01 23:00:00" "2017-02-01 23:00:00"
#> ..$ lo1 : num 143 143
#> $ data :List of 2
#> ..$ : num 0 0 0 0 0 0 0 0 0 0 ...
#> ..$ : num 0 0 0 0 0 0 0 0 0 0 ...
Created on 2022-02-28 by the reprex package (v2.0.1)