Распаковать столбцы json в фрейм данных

У меня есть строки json внутри столбца фрейма данных. Я хочу перенести все эти новые столбцы json в фрейм данных.

      # Input
JsonID <- as.factor(c(1,2,3))
JsonString1 = "{\"device\":{\"site\":\"Location1\"},\"tags\":{\"Engine Pressure\":\"150\",\"timestamp\":\"2608411982\",\"historic\":false,\"adhoc\":false},\"online\":true,\"time\":\"2608411982\"}"
JsonString2 = "{\"device\":{\"site\":\"Location2\"},\"tags\":{\"Engine Pressure\":\"160\",\"timestamp\":\"3608411983\",\"historic\":false,\"adhoc\":false},\"online\":true,\"time\":\"3608411983\"}"
JsonString3 = "{\"device\":{\"site\":\"Location3\"},\"tags\":{\"Brake Fluid\":\"100\",\"timestamp\":\"4608411984\",\"historic\":false,\"adhoc\":false},\"online\":true,\"time\":\"4608411984\"}"
JsonStrings = c(JsonString1, JsonString2, JsonString3)
Example <- data.frame(JsonID, JsonStrings)

Используя библиотеку jsonlite, я могу превратить каждую строку json в 1- строчный фрейм данных .

      library(jsonlite)

# One row dataframes
DF1 <- data.frame(fromJSON(JsonString1))
DF2 <- data.frame(fromJSON(JsonString2))
DF3 <- data.frame(fromJSON(JsonString3))

К сожалению, столбец переменной JsonID потерян. Все строки json имеют общее имя столбца, такое как «время». Но есть имена столбцов, которые они не разделяют. Путем более длительного поворота данных я мог связать все фреймы данных вместе.

      library(dplyr)
library(tidyr)

# Row bindable one row dataframes
DF1_RowBindable <- DF1 %>%
  rename_all(~gsub("tags.", "", .x)) %>% 
  tidyr::pivot_longer(cols = c(colnames(.)[2]))

Есть лучший способ сделать это?

Я никогда раньше не работал со строками json. Решение должно быть масштабируемым в вычислительном отношении.

1 ответ

Решение

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

      library(dplyr)
library(tidyr)
library(jsonlite)

Example %>%
  rowwise() %>%
  mutate(data = list(fromJSON(JsonStrings))) %>%
  unnest_wider(data) %>%
  select(-JsonStrings) %>%
  unnest_wider(tags) %>%
  unnest_wider(device)

# JsonID site      `Engine Pressure` timestamp  historic adhoc `Brake Fluid` online time      
#  <fct>  <chr>     <chr>             <chr>      <lgl>    <lgl> <chr>         <lgl>  <chr>     
#1 1      Location1 150               2608411982 FALSE    FALSE NA            TRUE   2608411982
#2 2      Location2 160               3608411983 FALSE    FALSE NA            TRUE   3608411983
#3 3      Location3 NA                4608411984 FALSE    FALSE 100           TRUE   4608411984

Поскольку каждый столбец ( data, tags, device) имеют разную длину, нам нужно использовать unnest_wider отдельно по каждому из них.

Другие вопросы по тегам