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