在R中从数据框底部开始逐行两两计算均值的实现问题
从数据框底部逐行计算两两均值的简洁实现
原始数据集
result_birth <- tibble::tibble( "1970" = c(8.816455, 21.41139, 39.0443, 51.639236, 59.196197, 100.759485, 76.829107, 103.278472, 79.348094, 99.499991, 81.867081, 78.088601), "1971" = c(18.878066, 30.204906, 42.790284, 65.443964, 69.219577, 80.546417, 114.526936, 94.390332, 108.234248, 83.063492, 103.200096, 72.99519), "1972" = c(8.801375, 22.632107, 36.462839, 56.580268, 69.153661, 76.697696, 80.469714, 109.388518, 96.815125, 108.131179, 69.153661, 91.785768), "1973" = c(14.675905, 20.790865, 31.797794, 64.818581, 58.70362, 86.832438, 85.609446, 96.616375, 97.839367, 78.271493, 105.177319, 53.811652) )
需求说明
需要从数据框底部开始,逐行两两计算均值,最后一行保留原数据:
- 倒数第二行 = (原倒数第二行 + 原最后一行) / 2
- 倒数第三行 = (原倒数第三行 + 计算后的倒数第二行) / 2
- 以此类推,直到第一行
原代码存在的问题:
- 计算方向错误:从顶部开始计算,导致第一行保留原数据,与需求不符
- 代码冗余:嵌套循环写法繁琐,效率低
解决方案
方法1:使用dplyr(简洁直观,适配tibble)
利用行反转+逐行处理,逻辑清晰:
library(dplyr) result_birth_processed <- result_birth %>% rev() %>% # 反转行顺序,原最后一行变为第一行 rowwise() %>% mutate(across(everything(), ~ ifelse(row_number() == 1, ., mean(c(., lag(.)))))) %>% ungroup() %>% rev() # 再次反转,恢复原行顺序
方法2:使用base R(无需额外依赖)
直接从后往前遍历,避免嵌套循环:
n_rows <- nrow(result_birth) result_birth_processed <- result_birth # 从倒数第二行开始向上遍历计算 for (i in (n_rows - 1):1) { result_birth_processed[i, ] <- (result_birth[i, ] + result_birth_processed[i + 1, ]) / 2 }
两种方法都能实现需求:最后一行保持原数据,从倒数第二行开始向上逐行计算两两均值。
内容的提问来源于stack exchange,提问作者Azam Mirzaei
相关产品推荐
相关产品推荐

