如何在 R 数据框中取消嵌套列表,同时保留键和值?

Posted

技术标签:

【中文标题】如何在 R 数据框中取消嵌套列表,同时保留键和值?【英文标题】:How do I unnest a list inside an R dataframe keeping both keys and values? 【发布时间】:2020-03-23 14:04:52 【问题描述】:

我目前正在将 JSON 格式的数据提取到 R 数据框中。

提供的数据格式如下:

创建测试数据的示例代码:

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)

我想做的是如下创建一个数据框:

我目前正在使用 RJSONIO::fromJSON() 函数将 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 代码的输出给了我以下信息:

但是,输入数据中的每一行都没有一组一致的键值对,因此我无法从行号推断键。例如,输入数据框中的第 3 行)中缺少“性别”

有什么想法吗?

【问题讨论】:

解析数据看起来有点奇怪。也许试试jsonlite::fromJSON()jsonlite::stream_in() 能否提供一些示例数据 @JBGruber - 我使用过 jsonlite,它给了我相同的结果。 @BertilBaron - 添加了测试数据 【参考方案1】:

您好,这是一个快速的解决方案。我正在使用每个 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)
)

希望这会有所帮助!

【讨论】:

谢谢伯蒂尔,确实如此!我在“取消透视”数据框后使用了 melt 功能,但这是我需要的步骤

以上是关于如何在 R 数据框中取消嵌套列表,同时保留键和值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在保留列表名称和值的同时展平一列列表? [r] [重复]

获取以索引为导向的嵌套字典中的键和值列表

将嵌套的键/值和嵌套列表合并到 json

Dev控件 ComboBoxEdit 如何绑定键和值

如何在scala中将嵌套映射[string,string]作为点分隔的键和值字符串

如何使用嵌套字典列表展平熊猫数据框中的列