Транспонирование списка словарей JSON для анализа в R - PullRequest
6 голосов
/ 14 февраля 2010

У меня есть экспериментальные данные, выраженные в виде диктов пар ключ-значение для каждого эксперимента. Ряд связанных экспериментов сериализуется как список этих диктовок в JSON. Это можно разобрать в R через пакет rjson, но данные загружаются в форму, которую сложно проанализировать

data <- fromJSON('[{"k1":"v1","k2":"v2"}, {"k1":"v3","k2":"v4"}]')

выходы

[[1]]
[[1]]$k1
[1] "v1"

[[1]]$k2
[1] "v2"


[[2]]
[[2]]$k1
[1] "v3"

[[2]]$k2
[1] "v4"

Попытка превратить это в data.frame напрямую с as.data.frame(data) выходами:

  k1 k2 k1.1 k2.1
1 v1 v2   v3   v4

четко просматривает последовательность пар ключ / значение во всех экспериментах в виде плоского одномерного списка.

Мне нужна более обычная таблица со строкой для каждого эксперимента и столбцом для каждого уникального ключа:

  k1 k2
1 v1 v2
2 v3 v4

Как я могу четко выразить это преобразование в R?

Ответы [ 2 ]

11 голосов
/ 14 февраля 2010

Функции l*ply могут стать вашим лучшим другом при работе со списком. Попробуйте это:

> library(plyr)
> ldply(data, data.frame)
  k1 k2
1 v1 v2
2 v3 v4

plyr выполняет очень приятную закулисную обработку, чтобы иметь дело с такими вещами, как нерегулярные списки (например, когда каждый список не содержит одинаковое количество элементов). Это очень распространено в JSON и XML, и с базовыми функциями сложно справиться.

Или, альтернативно, используя базовые функции:

> do.call("rbind", lapply(data, data.frame))

Вы можете использовать rbind.fill (из plyr) вместо rbind, если у вас неправильные списки, но я бы посоветовал просто использовать plyr с самого начала, чтобы облегчить вашу жизнь.

Edit:

Что касается вашего более сложного примера, использование предложения Хэдли легко решит эту проблему:

> x<-list(list(k1=2,k2=3),list(k2=100,k1=200),list(k1=5, k3=9))
> ldply(x, data.frame)
   k1  k2 k3
1   2   3 NA
2 200 100 NA
3   5  NA  9
4 голосов
/ 14 февраля 2010

Это интересно. Самым простым способом было бы исправить код Python, чтобы его легче было преобразовать.

Но как насчет этого?

k1 <- unlist(lapply(data,FUN=function(x){return(x[[1]])}))
k2 <- unlist(lapply(data,FUN=function(x){return(x[[2]])}))
data.frame(k1,k2)

Вам нужно будет преобразовать k1 ​​и k2 в правильный тип данных, но это должно выполнить то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...