如何使用zoo包按id分组计算height与组内首个height的差值?
按ID分组计算Height与组内首个值的差值实现方法
首先加载原始数据框:
# 加载原始数据框 df <- structure(list(id = c(80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80006L, 80016L, 80016L, 80016L, 80016L, 80016L, 80016L, 80024L, 80024L, 80024L, 80024L, 80024L, 80024L, 80024L, 80024L, 80024L), group = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), height = c(97.12, 101.35, 102.39, 103.49, 101.64, 105.88, 109.31, 107.37, 115.08, 116.83, 119.03, 117.01, 122.57, 132.27, 162.08, 105.01, 108.13, 115.58, 122.46, 130.33, 148.52, 89.78, 95.27, 98.99, 98.55, 100.84, 108.46, 109.49, 115.75, 118.52)), row.names = c(NA, 30L), class = "data.frame")
方法一:用dplyr直接计算(最直观)
借助dplyr的分组功能,直接让每组的height减去组内第一个height值:
library(dplyr) df <- df %>% group_by(id) %>% mutate(height_diff = height - first(height)) %>% ungroup()
运行后会新增height_diff列,每组第一个值为0,后续值为当前height与组内首值的差值。
方法二:用base R的diff + cumsum实现
通过拆分数据、计算相邻差值再累积求和的方式,得到和首值的差值:
df$height_diff <- unlist(lapply(split(df$height, df$id), function(x) { c(0, cumsum(diff(x))) }))
逻辑:diff(x)计算组内相邻height的差值,cumsum()累积这些差值就能得到当前值与首值的差,前面补0保证组第一个值为0,最后用unlist()合并结果回原数据框。
方法三:用zoo包实现
利用zoo包的函数提取组内首值,再计算差值:
library(zoo) # 方式1:结合dplyr分组 df <- df %>% group_by(id) %>% mutate(height_diff = height - first(zoo(height))) %>% ungroup() # 方式2:base R结合zoo df$height_diff <- unlist(lapply(split(df$height, df$id), function(x) { x - coredata(zoo(x))[1] }))
两种方式都能实现需求,核心是用zoo的工具获取组内第一个height值,再做减法运算。
内容的提问来源于stack exchange,提问作者Vons
相关产品推荐
相关产品推荐

