2016-12-06 12 views
4

Первый раз постер, долгое время lurker. Быть нежным. Умеренный пользователь R. Я уверен, что есть лучший, функциональный способ сделать то, что мне нужно, но почувствовал, что я исследовал смерть, не понимая.Как объединить данные в ранее существовавшую структуру JSON в R?

Я пытаюсь объединить набор данных с уже существующей структурой JSON. Где одна строка записей на структуру JSON для многих последовательных запросов JSON.

я загрузить набор данных к данным, 13 переменных и изменить заголовки столбцов, чтобы соответствовать, как они появляются в структуре JSON

library(jsonlite) 
#### Map Column headers to their respective names in the JSON Structure 
colnames(data) <- c("default.A", 
        "default.B", 
        "default.C", 
        "items.A", 
        "items.B.1", 
        "items.B.2", 
        "items.B.3", 
        "items.B.4", 
) 

Создание пустой JSON структуры. Это формат, для которого необходимо обрабатывать запросы JSON. Простая вложенная структура.

sample <- '{ 
     "default": { 
      "A": "", 
      "B": "", 
      "C": "", 
      }, 
     "items": [{ 
      "A": "", 
      "B": { 
       "1": "", 
       "2": "", 
       "3": "", 
       "4": "", 
        } 
       }] 
      }' 

jsonstructure <- fromJSON(sample) 

установить все как DF. объединить их. Заполните Nas холостыми

x <- as.data.frame(data) 
y <- as.data.frame(jsonstructure) 
Z <- merge(x, y, all = TRUE) 
Z[is.na(Z)] <- "" 

Преобразование в формат JSON

jsonZ <- toJSON(unname(split(Z, 1:nrow(Z))), pretty=TRUE) 
cat(jsonZ) 

Выходной ток, который не соответствует

[ 
    [ 
    { 
    "default.A": "", 
     "default.B": "1234567890", 
     "default.C": "", 
     "items.A": "1234567890", 
     "items.B.1": "1234", 
     "items.B.2": "1234", 
     "items.B.3": "1234", 
     "items.B.4": "1234", 
    } 
    ], 
    [ 
    { 
    "default.A": "", 
     "default.B": "0987654321", 
     "default.C": "", 
     "items.A": "0987654321", 
     "items.B.1": "4321", 
     "items.B.2": "4321", 
     "items.B.3": "4321", 
     "items.B.4": "4321", 
    } 
    ] 
] 

ответ

1

Не удалось воспроизвести ваши результаты - но вот моя догадка о том, чего вы хотите достичь. См. Комментарии для справки с кодом.

library(jsonlite) 

#data.frame with data - you have probably more than 2 rows 
data=data.frame(rbind(t(c(NA,1234567890,NA,1234567890,1234,1234,1234,1234)), 
         t(c(1,NA,2,3,1,1000,NA,1234)))) 

cn=c("default.A", 
     "default.B", 
     "default.C", 
     "items.A", 
     "items.B.1", 
     "items.B.2", 
     "items.B.3", 
     "items.B.4") 

colnames(data)=cn 

#assuming that "." represents structure 
mapping=strsplit(cn,"\\.") 

#template JSON 
jsonstructure <- fromJSON('{"default": {"A": "","B": "","C": ""}, 
          "items": [{"A": "", 
            "B": {"1": "","2": "","3": "","4": ""}}]}') 

#now loop through all rows in your data.frame and store them in JSON format 
#this will give you a list with JSON objects (i.e., a list of lists) 
json_list=lapply(split(data,1:nrow(data)),function(data_row) { 
    for (i in seq_along(mapping)) jsonstructure[[mapping[[i]]]]<-data_row[,cn[i]] 
    jsonstructure 
}) 

Результат:

toJSON(json_list[[2]],pretty = TRUE, auto_unbox=TRUE) 
#{ 
# "default": { 
# "A": 1, 
# "B": "NA", 
# "C": 2 
# }, 
# "items": [ 
# { 
#  "A": 3, 
#  "B": { 
#  "1": 1, 
#  "2": 1000, 
#  "4": 1234 
#  } 
# } 
# ] 
#} 

Просто еще один комментарий. Мой подход использует рекурсивное подмножество списков, как описан в справке к [ оператору:

[[может применяться рекурсивно к спискам, так что, если единственный индекс г является вектором длиной р, ALIST [ [i]] эквивалентно alist [[i1]] ... [[ip]], предоставляя все, кроме окончательных результатов индексации в списке.

+0

BTW: Я не выполнял обработку 'NA', но, я думаю, вы можете понять это сами. ;) – cryo111

+0

Я экспериментировал с этим, но сталкивался с некоторыми проблемами. При запуске вашей петли я получаю: 'Ошибка в 1: nrow (данные): аргумент длины 0' Я могу запустить ваш код как скопированный непосредственно из вашего сообщения. Наконец, глядя на конечный результат (и воспроизводимый с моего конца также), я вижу, что по какой-то причине данные, которые переполнены структурой JSON, иногда имеют кавычки вокруг значений NA, а не для остальных значений. – p0wd3rd

+0

ad error) Вы не указали 'data', но я предполагал, что это' data.frame', где каждая строка должна быть преобразована в объект 'JSON'. Если это так, эта ошибка, о которой вы сообщаете, не должна отображаться. Объявления не совпадают с «NA»). Я не знаю, как форматируется ваш фактический ввод, но вы можете приблизиться к тому, что хотите, с помощью 'jsonstructure [[mapping [[i]]] <- ifelse (is.na (data_row [, cn [i]]), "", as.character (data_row [, cn [i]])) ' – cryo111

0

Если ты не мертв набор на jsonlite пакет, вы можете попробовать rjson упаковка

library(rjson) 

value = c("", "1234690","") 
names(value) = c("A","B","C") 


value2 = c("","0987654321","","0987654321") 
names(value2) = c("1","2","3","4") 

test <- toJSON(list("default" = value, "items" = list(c("A" = "", "B" = list(value2))))) 
cat(test) 
writeLines(test, "test.json")