You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从深度嵌套列表提取指定元素并转换为R语言DataFrame

处理嵌套列表提取元素生成DataFrame的解决方案

问题场景

通过fromJSON()读取JSON文件得到一个深度嵌套列表(部分层级实际为数据框),需要从多个层级提取指定元素,将顶层元素(如PhraseText)与深层元素(如CandidateCUI)关联,生成目标DataFrame。

示例嵌套列表

conditions <- list(
  list(
    PMID = 00001,
    Phrases = list(
      list(
        PhraseText = "Hodgkin Lymphoma",
        Mappings = mappings1 <- list(
          list(
            MappingScore = 1000,
            MappingCandidates = mc1 <- list(
              list(CandidateScore = 1000,
                   CandidateCUI = "C075655",
                   CandidateMatched = "Hodgkins Lymphoma",
                   CandidatePreferred = "Hodgkins Lymphoma",
                   MatchedWords = list(c("hodgkin", "lymphoma"))),
              list(CandidateScore = 850,
                   CandidateCUI = "C095659",
                   CandidateMatched = "Lymphoma",
                   CandidatePreferred = "Lymphoma",
                   MatchedWords = list(c("lymphoma"))))
          )
        )
      )
    )
  ),
  list(
    PMID = 00002,
    Phrases = list(
      list(
        PhraseText = "Plaque Psoriasis",
        Mappings = mappings2 <- list(
          list(MappingScore = 1000,
               MappingCandidates = mc2 <- list(
                 list(CandidateScore = 1000,
                      CandidateCUI = "C0125609",
                      CandidateMatched = "Plaque Psoriasis",
                      CandidatePreferred = "Plaque Psoriasis",
                      MatchedWords = list(c("plaque", "psoriasis"))),
                 list(CandidateScore = 750,
                      CandidateCUI = "C0320011",
                      CandidateMatched = "Psoriasis",
                      CandidatePreferred = "Psoriasis",
                      MatchedWords = list(c("psoriasis"))))) 
        )
      )
    )
  )
)

目标DataFrame

output <- data.frame(
  PhraseText = c("Hodgkin Lymphoma", "Hodgkin Lymphoma", "Plaque Psoriasis", "Plaque Psoriasis"),
  MappingScore = c(1000, 1000, 1000, 1000),
  CandidateScore = c(1000, 850, 1000, 750),
  CandidateCUI = c("C075655", "C095659", "C0125609", "C0320011"),
  CandidatePreferred = c("Hodgkins Lymphoma", "Lymphoma", "Plaque Psoriasis", "Psoriasis")
)

用户尝试代码(存在关联问题)

x <- lapply(conditions, function(i) {
  lapply(i[["Phrases"]][[1]][["Mappings"]], function(j) {
    lapply(j[["MappingCandidates"]], function(k) {
      k[c("CandidateScore", "CandidateCUI", "CandidatePreferred")]
    })
  })
})

解决方案

方法1:使用purrr的map_dfr逐层绑定

通过三层嵌套的map_dfr,将上层的PhraseText、MappingScore传递到深层循环中,自动合并所有结果为DataFrame,完美关联各层级元素:

library(tidyverse)

result <- map_dfr(conditions, function(cond) {
  # 提取当前条目下的PhraseText
  phrase_text <- cond$Phrases[[1]]$PhraseText
  # 遍历每个Mapping对象
  map_dfr(cond$Phrases[[1]]$Mappings, function(map) {
    mapping_score <- map$MappingScore
    # 遍历每个候选对象,绑定上层字段
    map_dfr(map$MappingCandidates, function(cand) {
      tibble(
        PhraseText = phrase_text,
        MappingScore = mapping_score,
        CandidateScore = cand$CandidateScore,
        CandidateCUI = cand$CandidateCUI,
        CandidatePreferred = cand$CandidatePreferred
      )
    })
  })
})

# 转为data.frame格式(若需要)
result <- as.data.frame(result)

方法2:利用unnest系列函数扁平化结构(适合含数据框的层级)

如果嵌套结构中部分层级是数据框,使用tidyverse的unnest_wider和unnest可以更简洁地展开嵌套结构,直接提取所需字段:

library(tidyverse)

result <- tibble(data = conditions) %>%
  # 展开第一层列表为列
  unnest_wider(data) %>%
  # 展开Phrases下的嵌套内容
  unnest_wider(Phrases) %>%
  # 展开Mappings下的嵌套内容
  unnest_wider(Mappings) %>%
  # 展开MappingCandidates列表为多行
  unnest(MappingCandidates) %>%
  # 筛选需要的字段
  select(PhraseText, MappingScore, CandidateScore, CandidateCUI, CandidatePreferred)

# 转为data.frame格式(若需要)
result <- as.data.frame(result)

两种方法都能生成符合要求的目标DataFrame,方法1更通用适配纯列表结构,方法2在存在数据框层级时更高效简洁。

内容的提问来源于stack exchange,提问作者mark_ediger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:05:22