如何在 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] [重复]