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

如何用R对多数据框列表按标识合并并计算行均值?

问题描述

我有不同日期的高速路轮廓数据,需要计算月均速度并最终得到年均速度。目前已经用以下R脚本读取了目录下5个CSV文件,生成了包含5个数据框的列表:

# 读取速度数据
temp = list.files(pattern="*.csv")   #将目录下所有csv文件存入列表
list2env(
  lapply(setNames(temp, make.names(gsub("*.csv$", "", temp))), 
         read.csv), envir = .GlobalEnv)

# 将当前工作空间中的所有数据框存入列表:
rm(cbinded_df)
df_list = lapply(ls(), get)

所有数据框都包含40752条记录和6个字段,示例数据如下:

> head(export_route_contours_2019.01.01_2019.01.03)
  vehicle_type              time    link_id link_name offset_mi length_mi source_id avg_speed units
1          all Jan 01 2019 00:00 1049879368 I-405 (N)     0.000     0.042 106+04417      68.1   mph
2          all Jan 01 2019 00:00 1049879363 I-405 (N)     0.042     0.044 106+04417      67.8   mph
3          all Jan 01 2019 00:00 1049879364 I-405 (N)     0.086     0.145 106+04417      67.8   mph
4          all Jan 01 2019 00:00   28428436 I-405 (N)     0.231     0.021 106+04418      71.3   mph
5          all Jan 01 2019 00:00  835598783 I-405 (N)     0.252     0.015 106+04418      71.3   mph
6          all Jan 01 2019 00:00  835598784 I-405 (N)     0.267     0.052 106+04418      71.3   mph

核心需求:

  • 创建含40752条记录的合并数据框,存储各数据框avg_speed的平均值
  • 用循环或全局函数高效实现,避免逐个列出数据框名称
  • 以link_id与length_mi的组合作为记录标识符,确保路段数据正确关联

解决方案

方法1:dplyr + purrr高效处理(推荐)

直接通过列表操作数据,避免污染全局环境,代码简洁易维护:

library(dplyr)
library(purrr)

# 跳过list2env,直接读取CSV到列表(更规范)
temp <- list.files(pattern = "*.csv")
df_list <- map(temp, read.csv)

# 合并所有数据框并计算分组均值
avg_speed_df <- df_list %>%
  # 给每个数据框添加来源文件名(可选,用于溯源)
  imap(~ mutate(.x, source_file = .y)) %>%
  # 合并所有数据框
  bind_rows() %>%
  # 按路段标识分组,计算平均速度
  group_by(link_id, length_mi, vehicle_type, link_name, offset_mi, source_id, units) %>%
  summarise(avg_speed_mean = mean(avg_speed, na.rm = TRUE), .groups = "drop")

方法2:基础R实现(无需第三方包)

如果不想加载额外包,用基础R函数完成:

# 读取CSV到列表
temp <- list.files(pattern = "*.csv")
df_list <- lapply(temp, read.csv)

# 提取所需字段并合并成大数据框
combined_df <- do.call(rbind, lapply(df_list, function(df) {
  df[, c("link_id", "length_mi", "vehicle_type", "link_name", "offset_mi", "source_id", "units", "avg_speed")]
}))

# 计算分组平均速度
avg_speed_df <- aggregate(avg_speed ~ link_id + length_mi + vehicle_type + link_name + offset_mi + source_id + units, 
                          data = combined_df, 
                          FUN = function(x) mean(x, na.rm = TRUE))
# 重命名均值列
names(avg_speed_df)[names(avg_speed_df) == "avg_speed"] <- "avg_speed_mean"

封装为可重复调用的函数

针对你需要处理12个月及多路段的需求,封装函数可快速复用:

calculate_avg_speed <- function(csv_dir = getwd()) {
  setwd(csv_dir)
  temp <- list.files(pattern = "*.csv")
  df_list <- lapply(temp, read.csv)
  
  # 合并数据并提取关键字段
  combined_df <- do.call(rbind, lapply(df_list, function(df) {
    df[, c("link_id", "length_mi", "vehicle_type", "link_name", "offset_mi", "source_id", "units", "avg_speed")]
  }))
  
  # 计算均值
  avg_speed_df <- aggregate(avg_speed ~ link_id + length_mi + vehicle_type + link_name + offset_mi + source_id + units, 
                            data = combined_df, 
                            FUN = function(x) mean(x, na.rm = TRUE))
  names(avg_speed_df)[names(avg_speed_df) == "avg_speed"] <- "avg_speed_mean"
  
  return(avg_speed_df)
}

# 使用示例:传入CSV文件所在目录路径
# monthly_avg <- calculate_avg_speed("path/to/your/monthly/csvs")

关键注意点

  • 避免使用list2env将数据框放入全局环境,直接用列表处理更整洁,也不会造成环境变量混乱
  • 用link_id + length_mi作为分组键,确保每个路段的记录精准关联
  • 添加na.rm = TRUE处理可能的缺失值,防止计算出错
  • 封装的函数可直接应用于不同月份的CSV目录,重复操作效率更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:06:27