Как развернуть список внутри фрейма данных R, в котором хранятся ключи и значения? - PullRequest
0 голосов
/ 23 марта 2020

В настоящее время я работаю над извлечением данных в формате JSON в R-фрейм данных.

Данные представлены в следующем формате:

enter image description here

Пример кода для создания тестовых данных:

test_input_data <- data.frame(date.x=c("2017-08-17", "2017-07-26", "2017-10-04"), properties.x=c("{\"gender\": \"Male\", \"nationality\": \"NZL\", \"document_type\": \"passport\", \"date_of_expiry\": \"2018-07-05\", \"issuing_country\": \"NZL\"}", "{\"gender\": \"Female\", \"nationality\": \"NLD\", \"document_type\": \"national_identity_card\", \"date_of_expiry\": \"2026-10-07\", \"issuing_country\": \"NLD\"}" , "{\"issuing_date\": \"2015-05-18\", \"document_type\": \"driving_licence\", \"date_of_expiry\": \"2017-05-05\", \"issuing_country\": \"IRL\"}"), stringsAsFactors = FALSE)

Я хотел бы создать фрейм данных следующим образом:

enter image description here

В настоящее время я использую RJSONIO :: from JSON () функция для сопоставления properties.x в список и последующего его удаления:

properties_doc_reports <- test_data %>% 
  mutate(properties.x = map(properties.x, ~ RJSONIO::fromJSON(.))) %>% 
  dplyr::filter(purrr::map_lgl(properties.x, ~!rlang::is_empty(.x))) %>% ##this is optional as it deletes all rows with empty lists
  as_tibble %>% 
  unnest(properties.x)

Однако это избавляет от «ключа» в properties.x, который мне тоже нужен. Для справки, вывод кода R дает мне следующее:

enter image description here

Однако каждая строка во входных данных не имеет согласованного набора пары ключ-значение, поэтому невозможно определить ключ по номеру строки. Например, в строке 3) «пол» отсутствует во входном фрейме данных

Есть идеи?

1 Ответ

1 голос
/ 23 марта 2020

Привет, вот быстрое решение. Я использую тот факт, что каждый json содержит только одну строку. map_df из пакета purrr затем автоматически преобразует все строки в один data.frame. Так как map_df сохраняет порядок строк, это просто связать полученный df со столбцом даты.

test_input_data <- data.frame(date.x=c("2017-08-17", "2017-07-26", "2017-10-04"), properties.x=c("{\"gender\": \"Male\", \"nationality\": \"NZL\", \"document_type\": \"passport\", \"date_of_expiry\": \"2018-07-05\", \"issuing_country\": \"NZL\"}", "{\"gender\": \"Female\", \"nationality\": \"NLD\", \"document_type\": \"national_identity_card\", \"date_of_expiry\": \"2026-10-07\", \"issuing_country\": \"NLD\"}" , "{\"issuing_date\": \"2015-05-18\", \"document_type\": \"driving_licence\", \"date_of_expiry\": \"2017-05-05\", \"issuing_country\": \"IRL\"}"), stringsAsFactors = FALSE)

library(tidyverse)
df <- bind_cols(
  test_input_data %>% 
    select(date.x),
  test_input_data$properties.x %>% 
    map_df(jsonlite::fromJSON)
)

Надеюсь, это поможет !!

...