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

是否有比rowwise()更快的tibble单列逐行应用函数方法?

性能瓶颈分析
  • rowwise()属于R层面的逐行分组循环,每次函数调用都存在额外的分组环境调度开销,执行效率远低于直接遍历列表的映射函数
  • 原代码在逐行计算时重复生成3000次完全一致的先验分布样本rnorm(1e4, 0, 10),产生了大量无意义的计算消耗
  • 原代码对列表列每个元素重复执行unlist()操作,若列表列存储的本身就是数值向量,该操作属于多余的类型转换,会进一步拖慢速度
优化实现

基础优化:低代码改动版

首先将固定不变的先验样本提前生成,再用purrr::map_dbl替代rowwise()遍历列表列,无需改动核心计算逻辑即可获得明显提速:

library(tidyverse)
library(bayestestR)

# 提前一次性生成固定先验,避免循环内重复计算
set.seed(123)
fixed_prior <- rnorm(1e4, 0, 10)

# 示例数据
df <- tibble(idx = seq(1, 3000), beta = list(rnorm(4000, 0.5, 3)))

# 计算贝叶斯因子
df <- df %>%
  mutate(
    ioi = map_dbl(
      .x = beta,
      .f = ~ bayesfactor_parameters(
        posterior = .x,
        prior = fixed_prior,
        direction = "two-sided",
        null = c(-1, 1)
      )$log_BF
    )
  )

该版本相比原rowwise()实现可提速3~5倍。

进阶优化:并行计算版

由于每行贝叶斯因子的计算完全独立、无前后依赖,可通过并行计算进一步压缩耗时,使用和purrr语法兼容的furrr包即可快速实现并行:

library(furrr)

# 配置并行策略,核心数可根据自身CPU配置调整,建议预留1~2个核心避免系统卡顿
plan(multisession, workers = parallel::detectCores() - 1)

df <- df %>%
  mutate(
    ioi = future_map_dbl(
      .x = beta,
      .f = ~ bayesfactor_parameters(
        posterior = .x,
        prior = fixed_prior,
        direction = "two-sided",
        null = c(-1, 1)
      )$log_BF,
      .options = furrr_options(seed = TRUE)
    )
  )

# 计算完成后切回顺序执行模式
plan(sequential)

若使用8核CPU运行,该版本相比基础优化版可再提速56倍,原20分钟的计算任务可压缩至23分钟完成。

注意事项

如果你的beta列表列中存储的是嵌套列表结构而非直接的数值向量,可在.f参数内给.x套上unlist()即可,和原逻辑保持一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 00:37:03