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

如何对xts对象逐行使用vapply计算均值?哪种apply函数最优?

问题:用vapply计算xts对象每行均值,及最优apply函数选择

我有如下xts对象:

x <- structure(c(30440.5, 30441, 30441.5, 30441.5, 30441, 30439.5, 30440.5, 30441, 30441.5, NA, NA, 30439.5, NA, NA, NA, 30441.5, 30441, NA), .indexTZ = "", class = c("xts", "zoo"), .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", "POSIXt"), tzone = "", index = structure(c(1519866931.1185, 1519866931.1255, 1519866931.1255, 1519866931.1905, 1519866931.1905, 1519866931.1915), tzone = "", tclass = c("POSIXct", "POSIXt")), .indexFormat = "%Y-%m-%d %H:%M:%OS", .Dim = c(6L, 3L), .Dimnames = list(NULL, c("x", "y", "z")))

打印后样式如下:

# x y z
# 2018-03-01 09:15:31.118 30440.5 30440.5 NA
# 2018-03-01 09:15:31.125 30441.0 30441.0 NA
# 2018-03-01 09:15:31.125 30441.5 30441.5 NA
# 2018-03-01 09:15:31.190 30441.5 NA 30441.5
# 2018-03-01 09:15:31.190 30441.0 NA 30441.0
# 2018-03-01 09:15:31.191 30439.5 30439.5 NA

我想编写vapply代码,用mean(..., na.rm = TRUE)计算每行均值,得到如下单列结果:

w
2018-03-01 09:15:31.118 30440.5
2018-03-01 09:15:31.125 30441.0
2018-03-01 09:15:31.125 30441.5
2018-03-01 09:15:31.190 30441.5
2018-03-01 09:15:31.190 30441.0
2018-03-01 09:15:31.191 30439.5

我尝试多次仍无法实现。此外,很多回答建议我不要使用vapply,改用其他函数,但有资料显示vapply是最快的,请问此处哪种apply函数最优?


解答

一、用vapply实现每行均值计算

要实现这个需求,核心是抓住xts对象本质是带时间索引的矩阵这一点,我们可以逐行遍历计算均值,最后把结果包装回xts对象保留索引:

# 用vapply遍历每行,计算均值并指定返回类型为数值型
row_means <- vapply(seq_len(nrow(x)), function(i) {
  mean(x[i, ], na.rm = TRUE)
}, FUN.VALUE = numeric(1))

# 将计算结果转换为xts对象,保留原时间索引
w <- xts(row_means, index(x))
colnames(w) <- "w"

这段代码的关键点:

  • seq_len(nrow(x))生成每行的位置索引,供vapply逐个处理
  • FUN.VALUE = numeric(1)明确指定返回值类型,这也是vapply比sapply更高效的核心原因
  • 最后用原x的时间索引重新构建xts对象,确保时间信息不丢失

二、关于最优apply函数的讨论

你说的没错,vapply因为提前指定了返回类型,避免了sapply的动态类型检查,性能确实会更优,但针对这个场景,还有更合适的选择:

  1. rowMeans函数(绝对最优选择)
    这是R专门为矩阵/数据框设计的行均值计算函数,底层用C实现,速度远快于任何apply系列函数。针对你的xts对象,一行代码就能搞定:

    w <- xts(rowMeans(x, na.rm = TRUE), index(x))
    colnames(w) <- "w"
    

    代码简洁,性能拉满,完全没必要用apply系列函数绕弯。

  2. apply函数
    如果一定要用apply系列,apply(x, 1, mean, na.rm = TRUE)也能实现,但它返回的是普通向量,需要再转成xts,而且性能不如vapply和rowMeans。

  3. vapply vs sapply
    正如你了解的,vapply确实比sapply快,但在这个场景下,rowMeans的性能还是碾压vapply——毕竟是专门做行均值优化的底层函数。

总结:如果追求极致性能和简洁代码,rowMeans是毫无争议的最优选择;如果一定要用apply系列,vapply确实是其中最快的,但没必要舍近求远用它替代专用函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:20:46