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

如何基于条件将DataFrame转换为含子列表的嵌套列表(R语言)

通用实现DataFrame转指定嵌套列表的方法

问题背景

我正在做网页抓取项目,已经获取到目标数据,但无法转换成期望的嵌套列表格式。

示例输入数据

search_result <- structure(list(preferred_name = c("CHICAGO NORTHERLY ISLAND, IL", 
                                                   "CHICAGO MIDWAY AP, IL"), lat = c(41.8558, 41.78412), lng = c(-87.6094, 
                                                                                                                 -87.75514), distance = c(7.89027840950889, 17.4390740815157), 
                                GHCNMLT = c("USC00111550", "USW00014819"), WMO = c(NA, "72534014819"
                                )), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame"
                                ))

search_result包含站点名称、纬度、经度、距离及两种站点ID(GHCNMLT、WMO)。

转换规则

需要将该DataFrame转换为嵌套列表,保留站点名称、纬度、经度、距离,并按以下规则生成子列表:

  • 所有站点需生成对应GHCNMLT ID的valid_args_1子列表,包含ID、固定数据集和数据类型;
  • 若站点存在WMO ID(非NA),需额外生成valid_args_2子列表,包含ID、固定数据集和数据类型。

固定数据集与数据类型定义

GHCNMLT <- list(
  datasets = c("daily-summaries", "global-summary-of-the-month", "global-summary-of-the-year"),
  data_types = c("TMAX", "TMIN", "TAVG")
)

WMO <- list(
  datasets = c("local-climatological-data", "global-hourly"),
  data_types = c("HourlyDryBulbTemperature", "HourlyRelativeHumitidy")
)

期望输出结构

out <- list(
  # search_result第一行对应station_1
  station_1 = list(
    name = "CHICAGO NORTHERLY ISLAND, IL",
    lat = 41.9,
    lng = -87.8,
    distance = 7.89,
    valid_args_1 = list(
      ID_1 = "USC00111550",
      datasets = c("daily-summaries", "global-summary-of-the-month", "global-summary-of-the-year"),
      data_types = c("TMAX", "TMIN", "TAVG")
    )
  ),
  # search_result第二行对应station_2
  station_2 = list(
    name = "CHICAGO MIDWAY AP, IL",
    lat = 41.9,
    lng = -87.8,
    distance = 17.4,
    valid_args_1 = list(
      ID_1 = "USW00014819",
      datasets = c("daily-summaries", "global-summary-of-the-month", "global-summary-of-the-year"),
      data_types = c("TMAX", "TMIN", "TAVG")
    ),
    # 仅当WMO ID存在时添加valid_args_2
    valid_args_2 = list(
      ID_2 = "72534014819",
      datasets = c("local-climatological-data", "global-hourly"),
      data_types = c("HourlyDryBulbTemperature", "HourlyRelativeHumitidy")
    )
  )
)

请问当站点数量多于2个时,是否有通用的实现方法?

解决方案

可以通过purrr包的map函数遍历DataFrame的每一行,逐行构建嵌套列表,同时处理WMO ID的条件判断,实现通用化转换:

library(purrr)

# 定义转换函数,处理单行数据
convert_row <- function(row) {
  # 基础信息列表
  station_list <- list(
    name = row$preferred_name,
    lat = round(row$lat, 1), # 按示例保留一位小数
    lng = round(row$lng, 1),
    distance = round(row$distance, 2)
  )
  
  # 添加valid_args_1
  station_list$valid_args_1 <- list(
    ID_1 = row$GHCNMLT,
    datasets = GHCNMLT$datasets,
    data_types = GHCNMLT$data_types
  )
  
  # 若WMO ID存在,添加valid_args_2
  if (!is.na(row$WMO)) {
    station_list$valid_args_2 <- list(
      ID_2 = row$WMO,
      datasets = WMO$datasets,
      data_types = WMO$data_types
    )
  }
  
  return(station_list)
}

# 遍历所有行,生成站点列表
station_list <- map(1:nrow(search_result), function(i) {
  convert_row(search_result[i, ])
})

# 为列表元素命名(station_1、station_2...)
names(station_list) <- paste0("station_", 1:length(station_list))

# 查看结果
station_list

代码说明

  1. convert_row函数:接收单行数据,先构建包含基础信息的列表,再添加必填的valid_args_1,最后根据WMO ID是否存在决定是否添加valid_args_2;
  2. map遍历:使用map函数遍历DataFrame的每一行,对每行应用convert_row函数;
  3. 命名列表元素:通过paste0生成station_1、station_2这类命名,确保输出结构与期望一致;
  4. 小数处理:按示例对经纬度保留1位小数,距离保留2位小数,若不需要可去掉round函数。

这种方法不受站点数量限制,无论有多少个站点都能自动处理。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 08:22:48