如何在R语言中实现降序累积频率计算并添加数据框列
计算降序累积频率并添加到数据框
问题背景
现有如下R数据框:
Idle_min <- c(1, 2, 3, 5, 6, 8) Freq <- c(16, 11, 5, 7, 3, 1) df <- data.frame(Idle_min, Freq)
需要为其添加一个降序累积频率列:第一行是Freq列的总和,后续每行的累积值为前一行的累积值减去当前行的Freq,预期输出如下:
| Idle_min | Freq | cumulative |
|---|---|---|
| 1 | 16 | 43 |
| 2 | 11 | 27 (43-16) |
| 3 | 5 | 16 (27-11) |
| 5 | 7 | 11 (16-5) |
| 6 | 3 | 4 (11-7) |
| 8 | 1 | 1 (4-3) |
解决方案
方法1:基础R实现
核心思路是先计算Freq的总和,再通过反向累积和的方式得到降序累积值,若需要显示计算过程,可将数值与公式拼接为字符串:
# 计算Freq列的总和 total_freq <- sum(df$Freq) # 生成纯数值的降序累积列 df$cumulative <- total_freq - c(0, cumsum(df$Freq[-nrow(df)])) # 生成带计算过程的标签列(匹配预期输出格式) df$cumulative_label <- mapply(function(val, prev_val, prev_freq, idx) { if (idx == 1) { as.character(val) } else { paste0(val, " (", prev_val, "-", prev_freq, ")") } }, df$cumulative, c(NA, df$cumulative[-nrow(df)]), c(NA, df$Freq[-nrow(df)]), seq_len(nrow(df)))
方法2:tidyverse(dplyr)实现
如果习惯使用tidyverse语法,可通过mutate结合lag函数快速实现:
library(dplyr) df <- df %>% mutate( # 计算Freq总和 total = sum(Freq), # 生成降序累积数值列 cumulative = total - lag(cumsum(Freq), default = 0), # 生成带计算过程的标签列 cumulative_label = case_when( row_number() == 1 ~ as.character(cumulative), TRUE ~ paste0(cumulative, " (", lag(cumulative), "-", lag(Freq), ")") ) )
执行上述代码后,df会新增cumulative(纯数值)和cumulative_label(带公式的字符串)两列,其中cumulative_label完全匹配预期输出格式。
内容的提问来源于stack exchange,提问作者Niro Mal
相关产品推荐
相关产品推荐

