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

如何在R中按每n行计算tibble均值并添加对应新列?

外汇报价数据按5行分组计算均值并填充

我有一个存储外汇报价的tibble,每天包含5条买入价和5条卖出价记录(即每日5行2列数据)。需要实现一个迭代方案,遍历数据计算每5行的总和与均值,并将结果重复填充到对应行的新列中。

示例数据:

buyPrice <- c(1:10)
sellPrice <- c(11:20)

exchange <- tibble(buyPrice, sellPrice)

期望处理后新增averageBuy和averageSell列,前5行均值分别为3和13,后5行分别为8和18。

我尝试用以下循环函数实现,但代码中averageList[(i-4):i] <- rep(average,5)赋值失败,函数返回NULL:

getAverageByDay <- function(dataSet, columnNumber) {
  
  temporarySum <- 0
  average <- c()
  dataSetRows <- nrow(dataSet)
  averageList <- rep(0,dataSetRows)
  
  for (i in 1:dataSetRows) {
    if (i %% 5 == 0) {
      temporarySum <- temporarySum + dataSet[[i,columnNumber]]
      
      average <- temporarySum / 5 
     
      averageList[(i-4):i] <- rep(average,5)
      
      temporarySum <- 0
      average <- 0
      
    } else {
      temporarySum <- temporarySum + dataSet[[i,columnNumber]] 
    }
  }
  return(averageList)
}

循环代码问题分析与修复

循环代码的核心问题是数据提取方式错误:dataSet[[i,columnNumber]]是列表元素的提取语法,不适用于tibble的行列位置访问。另外代码存在冗余的变量初始化(比如average <- c())。

修复后的循环函数:

getAverageByDay <- function(dataSet, columnNumber) {
  
  temporarySum <- 0
  dataSetRows <- nrow(dataSet)
  averageList <- rep(0, dataSetRows)
  # 提前提取目标列向量,提升循环效率
  target_col <- dplyr::pull(dataSet, columnNumber)
  
  for (i in 1:dataSetRows) {
    temporarySum <- temporarySum + target_col[i]
    if (i %% 5 == 0) {
      average <- temporarySum / 5 
      averageList[(i-4):i] <- rep(average, 5)
      temporarySum <- 0
    }
  }
  return(averageList)
}

# 调用函数生成新列
exchange$averageBuy <- getAverageByDay(exchange, "buyPrice")
exchange$averageSell <- getAverageByDay(exchange, "sellPrice")

符合R语言特性的高效实现

R的核心优势是向量化操作,无需循环即可高效完成分组计算,以下是三种常用方案:

1. dplyr分组(语法直观,适合一般场景)

利用dplyr的分组功能,按每5行创建分组标识,计算均值后自动填充到组内所有行:

library(dplyr)

exchange <- exchange %>%
  # 生成分组ID:每5行一组
  mutate(group = (row_number() - 1) %/% 5) %>%
  group_by(group) %>%
  mutate(
    averageBuy = mean(buyPrice),
    averageSell = mean(sellPrice)
  ) %>%
  ungroup() %>%
  # 可选:删除分组标识列
  select(-group)

2. Base R 向量化操作(无需额外包)

用base R的ave函数结合分组标识,实现分组均值填充:

# 生成每5行一组的标识
group_id <- (seq(nrow(exchange)) - 1) %/% 5

# 计算并填充均值
exchange$averageBuy <- ave(exchange$buyPrice, group_id, FUN = mean)
exchange$averageSell <- ave(exchange$sellPrice, group_id, FUN = mean)

3. data.table(大数据量场景最优)

如果数据量较大,data.table的分组计算性能远优于循环和dplyr:

library(data.table)

# 转换为data.table格式
setDT(exchange)[, `:=`(
  averageBuy = mean(buyPrice),
  averageSell = mean(sellPrice)
), by = .(group = (seq_len(.N) - 1) %/% 5)]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:45:58