如何在分组列表列中捕获各模拟的最大值?
分组列表列的逐位置最大值计算方案
核心实现代码
要在分组状态下自动适配任意条件数,对列表列的每个模拟位置取最大值,可以通过**收集组内所有列表并逐位置应用pmax()**实现:
library(tidyverse) POST_SIMS <- 4 CONDITIONS <- 3 DURATION <- 2 set.seed(42) # 固定随机种子确保结果可复现 df <- tibble( day = rep(1:DURATION, each = CONDITIONS), condition = rep(LETTERS[1:CONDITIONS], times = DURATION), ) |> rowwise() |> mutate(post = list(rnorm(POST_SIMS, 0, 1))) # 生成post_max列表列 df_result <- df |> group_by(day) |> mutate( # 收集当前组所有条件的post列表,形成一个嵌套列表 all_posts = list(post), # 对每个模拟位置,取所有条件的最大值,生成长度为POST_SIMS的向量 post_max = list(pmap_dbl(all_posts, pmax)) ) |> ungroup() |> select(-all_posts) # 移除临时辅助列
代码说明
- 原代码问题:之前直接用
pmap(list(post), pmax)时,分组后的list(post)是每行单独的列表,pmap仅对单个列表执行pmax,结果就是原列表重复,无法实现跨条件取最大值。 - 关键改进:通过
list(post)收集组内所有条件的post列表,形成一个包含多个等长向量的列表,再用pmap_dbl遍历每个位置,取所有条件对应位置的最大值,最终得到每个组的4个模拟最大值列表。
验证结果
可以手动计算验证结果是否正确:
# 提取第1天的所有post列表 day1_posts <- df |> filter(day == 1) |> pull(post) # 手动计算逐位置最大值 manual_max <- pmap_dbl(day1_posts, pmax) # 对比结果中的post_max df_result |> filter(day == 1) |> pull(post_max) |> first() manual_max
替代实现方法(嵌套处理)
也可以通过nest先按天聚合数据,处理后再展开,逻辑更直观:
df_result2 <- df |> nest(data = -day) |> mutate( # 对每个天的所有post计算逐位置最大值 post_max = map(data, ~pmap_dbl(.x$post, pmax)), # 将最大值列表添加到每个条件行 data = map2(data, post_max, ~mutate(.x, post_max = list(.y))) ) |> unnest(data)
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

