R list(структура (list())) к фрейму данных

У меня есть источник данных JSON, предоставляющий список хэшей:

[
  { "a": "foo",
    "b": "sdfshk"
  },
  { "a": "foo",
    "b": "ihlkyhul"
  }
]

я использую fromJSON() в rjson пакет для преобразования этого в структуру данных R. Возвращает:

list(
  structure(list(a = "foo", b = "sdfshk"), .Names = c("a", "b")),
  structure(list(a = "foo", b = "ihlkyhul"), .Names = c("a", "b"))
)

Мне нужно, чтобы получить это в кадре данных R, но data.frame() превращает это в однорядный фрейм данных с четырьмя столбцами вместо фрейма данных 2x2, как и ожидалось. Мне не хватает R-fu для преобразования из одного в другое, хотя, похоже, все должно быть просто.

Бонусные очки:

Фактическая проблема немного сложнее, потому что источник данных JSON не такой регулярный, как показано выше. Возвращаемые объекты различаются по типу. Таким образом, поле, установленное в каждом, может быть одного из нескольких различных типов:

[
  { "a": "foo",
    "b": "asdfhalsdhfla"
  },
  { "a": "bar",
    "c": "akjdhflakjhsdlfkah",
    "d": "jfhglskhfglskd",
  },
  { "a": "foo",
    "b": "dfhlkhldsfg"
  }
]

Как видите, поле "a" в каждом объекте является тегом типа, указывающим, какие другие поля будет иметь объект.

Я не слишком конкретен, как решение справляется с этим.

Не было бы ужасно, если бы два типа объектов были просто смешаны вместе, поэтому вы получаете столбцы a, b, c и d, а строки просто имеют N/A или же NULL значения, в которых исходный объект JSON не имеет значения для данного поля. Я считаю, что могу очистить результирующий фрейм данных subset(df, a == "foo"), Таким образом, я получу несколько пустых столбцов, но это не будет иметь значения для моей программы.

Было бы лучше, если бы решение предоставило способ выбрать, какие исходные строки JSON попадают в фрейм данных, а какие отклоняются, чтобы в результате были фактически только нужные столбцы и строки.

1 ответ

Решение

Если у вас есть зубчатый список, который вы хотите преобразовать в data.frame, вы можете использовать plyr Хэдли rbind.fill, Спасла мою шею пару раз. Дайте мне знать, если это то, что вы ищете. Обратите внимание, что я изменил ваш первый пример, добавив только "b" в третий элемент, чтобы сделать его неровным.

> x <- list(
+         structure(list(a = "foo", b = "sdfshk"), .Names = c("a", "b")),
+         structure(list(a = "foo", b = "ihlkyhul"), .Names = c("a", "b")),
+         structure(list(b = "asdf"), .Names = "b")
+ )
> 
> library(plyr)
> do.call("rbind.fill", lapply(x, as.data.frame))
     a        b
1  foo   sdfshk
2  foo ihlkyhul
3 <NA>     asdf
Другие вопросы по тегам