R语言中基于CURR_PR变量更新BRR列值的后续技术问题
问题描述
这是此前问题的后续。现有如下数据框:
ID <- c('A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A' ) EXP_P <- c(62,62,62,62,62,62,62,64,64,64,67,67,67,67,67,67) BRR <- c(61,57,66,53,54,50,55,65,71,53,51,50,58,54,55,57) val1 <- c(1,1,1,1,1,1,1,2,2,2,3,3,3,3,3,3) CURR_PR <- c(1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,3) df <- data.frame(ID, EXP_P, BRR, val1, CURR_PR)
初始输出:
ID EXP_P BRR val1 CURR_PR 1 A 62 61 1 1 2 A 62 57 1 1 3 A 62 66 1 1 4 A 62 53 1 1 5 A 62 54 1 1 6 A 62 50 1 1 7 A 62 55 1 1 8 A 64 65 2 2 9 A 64 71 2 2 10 A 64 53 2 2 11 A 67 51 3 2 12 A 67 50 3 3 13 A 67 58 3 3 14 A 67 54 3 3 15 A 67 55 3 3 16 A 67 57 3 3
已通过以下代码实现依赖多变量的BPP列计算:
df %>% group_by(ID, val1) %>% mutate(occ = row_number()) %>% group_by(ID) %>% mutate( BPP = case_when( occ == 1 ~ EXP_P, occ == 2 ~ lag(BRR), occ == 3 ~ pmax(lag(BRR, 1), lag(BRR, 2), na.rm = TRUE), TRUE ~ pmax(lag(BRR, 1), lag(BRR, 2), lag(BRR, 3), na.rm = TRUE) ) ) %>% ungroup()
计算结果:
# # A tibble: 16 × 6 # ID EXP_P BRR val1 occ BPP # <chr> <dbl> <dbl> <dbl> <int> <dbl> # 1 A 62 61 1 1 62 # 2 A 62 57 1 2 61 # 3 A 62 66 1 3 61 # 4 A 62 53 1 4 66 # 5 A 62 54 1 5 66 # 6 A 62 50 1 6 66 # 7 A 62 55 1 7 54 # 8 A 64 65 2 1 64 # 9 A 64 71 2 2 65 # 10 A 64 53 2 3 71 # 11 A 67 51 3 1 67 # 12 A 67 50 3 2 51 # 13 A 67 58 3 3 51 # 14 A 67 54 3 4 58 # 15 A 67 55 3 5 58 # 16 A 67 57 3 6 58
新需求
当CURR_PR值发生变化时,需将对应组的第一个BRR值替换为前一个CURR_PR组的第一个BRR值:
CURR_PR=1时,第一个BRR为61;CURR_PR变为2时,该组第一个BRR需替换为CURR_PR=1组的第一个BRR(即61);CURR_PR变为3时,该组第一个BRR需替换为CURR_PR=2组更新后的第一个BRR(即61);
注:该替换值会随后续case_when的计算动态更新,并非固定为61。
期望输出(更新后的BRR列):
ID EXP_P BRR val1 CURR_PR 1 A 62 61 1 1 2 A 62 57 1 1 3 A 62 66 1 1 4 A 62 53 1 1 5 A 62 54 1 1 6 A 62 50 1 1 7 A 62 55 1 1 8 A 64 61 2 2 9 A 64 71 2 2 10 A 64 53 2 2 11 A 67 51 3 2 12 A 67 61 3 3 13 A 67 58 3 3 14 A 67 54 3 3 15 A 67 55 3 3 16 A 67 57 3 3
解决方案
可以通过以下步骤实现需求:
- 标记每个
CURR_PR组的首行; - 提取每个
CURR_PR组的初始首行BRR值,并关联前一组的首行BRR值; - 替换当前组首行的
BRR值为前一组的首行BRR; - 基于更新后的
BRR计算BPP列。
完整代码:
library(dplyr) # 步骤1:处理BRR的替换逻辑 df_updated <- df %>% group_by(ID, CURR_PR) %>% mutate(is_first = row_number() == 1) %>% ungroup() %>% # 提取每个CURR_PR组的第一个BRR值 group_by(ID, CURR_PR) %>% summarise(first_brr = first(BRR), .groups = "drop") %>% # 计算前一个CURR_PR组的first_brr group_by(ID) %>% mutate(prev_first_brr = lag(first_brr)) %>% ungroup() %>% # 关联回原数据,替换首行BRR right_join(df, by = c("ID", "CURR_PR")) %>% mutate( BRR = ifelse(is_first & !is.na(prev_first_brr), prev_first_brr, BRR) ) %>% select(-is_first, -first_brr, -prev_first_brr) # 步骤2:基于更新后的BRR计算BPP final_df <- df_updated %>% group_by(ID, val1) %>% mutate(occ = row_number()) %>% group_by(ID) %>% mutate( BPP = case_when( occ == 1 ~ EXP_P, occ == 2 ~ lag(BRR), occ == 3 ~ pmax(lag(BRR, 1), lag(BRR, 2), na.rm = TRUE), TRUE ~ pmax(lag(BRR, 1), lag(BRR, 2), lag(BRR, 3), na.rm = TRUE) ) ) %>% ungroup() # 查看更新后的BRR列(符合期望输出) final_df %>% select(ID, EXP_P, BRR, val1, CURR_PR)
代码说明
- 首先通过分组标记每个
CURR_PR组的首行,然后提取每组的首行BRR值,用lag()获取前一组的对应值; - 通过
right_join将前组首行BRR关联回原数据,替换当前组首行的BRR(仅当当前组不是第一个CURR_PR组时); - 最后使用更新后的
BRR列,沿用之前的逻辑计算BPP值,确保后续计算基于最新的BRR数据。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

