如何使用dplyr将数据框分组的最后一行计算列值设为0?
用dplyr实现分组最后一行的Calculate列置0
问题场景
先回顾下你的初始数据和需求:
我们有这个数据框:
ID <- c(1, 1, 1, 5, 5) Period <- c(1,2,3,1,2) Value <- c(10,12,11,4,6) df <- data.frame(ID, Period, Value)
它的结构是:
ID Period Value
1 1 1 10
2 1 2 12
3 1 3 11
4 5 1 4
5 5 2 6
你已经用dplyr的mutate算出了Calculate = Period * Value,现在需要修改规则:每个ID分组的最后一行,把Calculate列改成0,最终要得到这样的结果:
ID Period Value Calculate
1 1 1 10 10
2 1 2 12 24
3 1 3 11 0
4 5 1 4 4
5 5 2 6 0
你之前考虑用lead()但担心末尾的表现,其实完全没问题,这里给你两种可靠的实现方法:
方法一:用行号判断(最直观)
这种方法直接通过分组内的行号来识别最后一行,逻辑清晰,容易理解:
library(dplyr) df_final <- df %>% group_by(ID) %>% mutate(Calculate = ifelse(row_number() == n(), 0, Period * Value)) %>% ungroup()
group_by(ID):先按ID分组,确保我们只在同一个ID的范围内判断row_number():拿到当前行在分组里的序号n():获取当前分组的总行数- 逻辑判断:如果当前行是分组的最后一行(行号等于总行数),就把Calculate设为0,否则用Period和Value的乘积
方法二:用lead()函数(贴合你的初始思路)
如果你还是想用lead(),其实不用担心数据框末尾的情况——lead(ID)在分组的最后一行会返回NA,我们刚好可以用这个特性来判断:
df_final <- df %>% group_by(ID) %>% mutate(Calculate = ifelse(is.na(lead(ID)), 0, Period * Value)) %>% ungroup()
lead(ID):获取下一行的ID值,分组的最后一行没有下一行,所以会返回NAis.na(lead(ID)):如果这个判断为TRUE,就说明当前行是分组最后一行,把Calculate设为0,否则计算乘积
两种方法都能完美得到你想要的结果,第一种更直白,第二种适合你原本的思路延伸,选哪个都可以~
内容的提问来源于stack exchange,提问作者Curious Jorge - user9788072
相关产品推荐
相关产品推荐

