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

如何将嵌套列表键转为DataFrame列并拆分两队玩家数据

高效拆分嵌套列表列(teams)为玩家独立列的R方案

问题场景

从JSON文件读取得到raw_data DataFrame,其中大部分列可通过unnest顺利展开为非列表列,但teams列是特殊的嵌套列表结构——每个元素包含玩家1和玩家2的字典数据(含profile_id、result等键)。直接用unnest会丢失其中一方的玩家数据,需要将两个玩家的对应键拆分为独立列(如profile_id_p1、profile_id_p2),且最终所有列均为非列表格式。

原方案通过循环+append提取玩家数据,效率较低,以下是更高效的优化方案:


方案1:基于tidyverse的函数式实现(简洁易读)

利用purrr的向量化映射函数替代显式循环,结合dplyr和tidyr完成数据合并:

library(dplyr)
library(purrr)
library(tidyr)

# 处理teams列:拆分每个元素的p1/p2数据,重命名键后合并为DataFrame
processed_teams <- raw_data$teams %>%
  map_dfr(function(player_pair) {
    # 提取玩家1数据并添加_p1后缀
    p1_data <- player_pair[[1]] %>% set_names(paste0(names(.), "_p1"))
    # 提取玩家2数据并添加_p2后缀
    p2_data <- player_pair[[2]] %>% set_names(paste0(names(.), "_p2"))
    # 合并单条记录的p1/p2数据
    c(p1_data, p2_data)
  })

# 合并到原数据:先展开其他列表列,再绑定处理后的teams数据
final_df <- raw_data %>%
  select(-teams) %>%  # 移除原teams列
  unnest(cols = everything()) %>%  # 展开其他列表列
  bind_cols(processed_teams)

方案2:基于data.table的高效实现(大数据量首选)

延续原方案中rbindlist的思路,用lapply替代循环+append,减少内存重复分配:

library(data.table)
library(tidyr)

# 用lapply批量提取每个teams元素的p1/p2数据(避免循环append的内存开销)
p1_dic <- lapply(raw_data$teams, `[[`, 1)
p2_dic <- lapply(raw_data$teams, `[[`, 2)

# 转为data.table并添加列后缀
p1_df <- rbindlist(p1_dic) %>% setnames(paste0(names(.), "_p1"))
p2_df <- rbindlist(p2_dic) %>% setnames(paste0(names(.), "_p2"))

# 合并原数据
final_df <- raw_data %>%
  select(-teams) %>%
  unnest(cols = everything()) %>%
  bind_cols(p1_df, p2_df)

优化说明

  1. 避免低效循环:原方案的for循环+append会反复修改向量并重新分配内存,而lapply/map_dfr是向量化操作,内存分配更高效,处理大数据量时速度提升明显。
  2. 直接映射处理:通过单次映射完成玩家数据的提取、重命名与合并,代码更简洁,可读性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 18:25:26