R语言中使用purrr::accumulate对嵌套tibble进行累积计算时初始值未正确传递的问题
问题分析与解决
你的核心问题出在分组状态下的mutate执行逻辑:因为你最初的tibble是按ID分组的,当你在mutate中调用accumulate时,R会对每个ID分组单独运行accumulate,导致每个分组都从初始值1000开始计算,完全无法跨ID传递累积结果——这就是第二个G_i错误使用1000而非2030的原因。
修正代码
只需要先取消分组,让accumulate能遍历所有data元素并连续传递累积值即可:
tab <- data.frame(A = c("A","B","A","B"), ID = c(1,1,2,2), V1 = c(20,40,25,30), V2 = c(0.2,0.8,0.3,0.7) ) %>% group_by(ID) %>% nest() # 修正后的代码 tab %>% ungroup() %>% # 关键步骤:解除分组,让accumulate跨ID处理 mutate( G_i = purrr::accumulate(data, function(prev_total, group_data) { # 用传入的上一次累积值计算当前分组的总和 group_data %>% group_by(A) %>% mutate(current_G = prev_total + prev_total * V2 / V1) %>% pull(current_G) %>% sum() }, .init = 1000) %>% tail(-1) # 移除初始值,只保留每个ID对应的计算结果 )
运行结果
执行后会得到你期望的输出:
# A tibble: 2 × 3 ID data G_i <dbl> <list> <dbl> 1 1 <tibble [2 × 3]> 2030 2 2 <tibble [2 × 3]> 4131.727
细节说明
ungroup()的作用:解除原有的ID分组约束,确保accumulate能对整个data列的两个元素进行连续计算,第一个分组的结果会作为第二个分组的初始值传入。- 参数命名优化:把函数参数改为
prev_total和group_data,更直观地表示“上一次的累积总和”和“当前要处理的分组数据”。 - 简化求和逻辑:用
pull(current_G) %>% sum()替代原代码的sum(out$G_i),逻辑完全一致但更简洁可读。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

