R语言实现滚动和<20分组:能否用map函数替代for循环
解答
可以实现,但更合适的是使用purrr包中的accumulate函数(属于map系列工具,专门处理带状态的累积计算)。普通map是无状态的元素映射,无法直接跟踪滚动和与当前组号这两个需要延续的状态,而accumulate可以在迭代过程中传递状态,完美匹配你的分组逻辑。
实现代码
library(purrr) # 定义状态处理函数:输入上一轮状态和当前值,返回新状态 update_group <- function(state, current_val) { new_sum <- state$rolling_sum + current_val if (new_sum > 20) { # 开启新分组,重置滚动和为当前值 list(rolling_sum = current_val, group = state$group + 1) } else { # 保留当前分组,更新滚动和 list(rolling_sum = new_sum, group = state$group) } } # 初始状态:滚动和为0,起始组号为1 initial_state <- list(rolling_sum = 0, group = 1) # 累积计算每个元素对应的状态 all_states <- accumulate(data$row, update_group, .init = initial_state) # 提取每个元素的组号(剔除初始状态) groups <- map_int(all_states[-1], ~ .x$group) # 合并结果 result <- data.frame(data, groups) print(result)
代码说明
accumulate会依次将每个row值传入update_group函数,同时传递上一轮的状态(滚动和+组号),完全替代for循环中的状态跟踪逻辑。map_int从每个状态对象中提取组号,转换为整数向量。- 运行结果与原for循环完全一致:
row groups 1 1 1 2 2 1 3 3 1 4 4 1 5 5 1 6 6 2 7 7 2 8 8 3 9 9 3 10 10 4
如果一定要局限于“map”这个名称,accumulate本身就是purrr包map家族的成员,是处理这类带状态迭代的最优选择,而非普通的map函数。
内容的提问来源于stack exchange,提问作者jkatam
相关产品推荐
相关产品推荐

