Конвертировать данные кадра в JSON в R

У меня есть фрейм данных df, который я хотел бы преобразовать в формат json:

df <- data.frame(`ArtId` = rep(c(50,70),each=4), 
  `Year` = rep(1990:1993,times=2), 
  `IndexBV` = c(132,94,83,101,100,100,67,133), 
  `SE` = c(20,15,12,13,NA,NA,NA,NA))

ArtId Year IndexBV SE
50    1990 132     20
50    1991  94     15
50    1992  83     12
50    1993 101     13
70    1990 100     NA
70    1991 110     NA
70    1992  67     NA
70    1993 133     NA

Кадр данных содержит значения индекса (IndexBV) и их стандартные ошибки (SE) для двух разных видов (ArtId 50 и 70) за 1990-1993 годы.

Когда я делаю:

cat(jsonlite::toJSON(df, pretty=T))

Я получаю это (показаны только первые два элемента):

[
  {
    "ArtId": 50,
    "Year": 1990,
    "IndexBV": 132,
    "SE": 20
  },
  {
    "ArtId": 50,
    "Year": 1991,
    "IndexBV": 94,
    "SE": 15
  },
... 

Но то, что мне нужно по желанию. Res это структура, которая выглядит следующим образом при печати с cat(jsonlite::toJSON(desired.res, pretty=T)):

{
    "Year":["1990","1991","1992","1993"],
    "ArtId": {
        "50":[
            {"IndexBV": 132, "SE": 20},
            {"IndexBV": 94, "SE": 15},
            {"IndexBV": 83, "SE": 12},
            {"IndexBV": 101, "SE": 13}
        ],
        "70":[
            {"IndexBV": 100, "SE": NA},
            {"IndexBV": 110, "SE": NA},
            {"IndexBV": 67, "SE": NA,
            {"IndexBV": 133, "SE": NA}
        ]
    }
}

Как я могу конвертировать df в требуемый.res? Я думаю, что проблема заключается в преобразовании df во вложенный список, чтобы учесть его вложенную структуру.

1 ответ

Решение

Я могу дать очень конкретное решение, но для обобщения потребуется больше работы, так как это странный формат для меня. Попробуйте это, и приспособьтесь, чтобы сделать соответственно более устойчивым, например, год, идущий от длины 8 до длины 4.

# I find data.table easier
library(data.table)
dt <- as.data.table(df)

# manually can do it, find levels of L, split data and name
L <- unique(df$ArtId)
ArtList <- lapply(L, function(x){
  x.dt <- dt[ArtId == x, .(IndexBV, SE)]
  x.dt
})
names(ArtList) <- L

# combine in to one list
X <- list(Year=unique(dt$Year),
          ArtId = ArtList)

# convert to Json, need either "null" or "string" for na, else dropped
jsonlite::toJSON(X, pretty = TRUE, na="null")
Другие вопросы по тегам