如何在tidyverse中批量执行transmute差分计算?
解决方法
可以用tidyverse工具链实现这个需求,直接看具体步骤和代码:
- 先把数据转成长格式,拆分列名的前缀和编号;
- 按前缀分组,计算组内后一个编号对应值减去前一个编号对应值的差值;
- 过滤掉没有前序编号的项,再转回宽格式,最后和原数据的A列合并。
具体代码如下:
library(tidyverse) # 构造示例数据 df <- tibble( A = rep("A",10), xyz1 = rnorm(10), xyz2 = rnorm(10), xyz3 = rnorm(10), abc1 = rnorm(10), abc2 = rnorm(10), abb3 = rnorm(10), acc4 = rnorm(10) ) # 处理逻辑 result <- df %>% # 保留A列,其他列转长格式 pivot_longer(cols = -A, names_to = "col", values_to = "val") %>% # 拆分列名为前缀prefix和数字编号num mutate( prefix = str_extract(col, "^[a-z]+"), num = as.integer(str_extract(col, "\\d+$")) ) %>% # 按A和前缀分组,确保编号有序 group_by(A, prefix) %>% arrange(num, .by_group = TRUE) %>% # 计算当前值减前一个值,只保留有前序编号的行 mutate( val = val - lag(val), col = col[num > 1], val = val[num > 1] ) %>% # 去掉无有效计算结果的行 drop_na(col, val) %>% ungroup() %>% # 转回宽格式 pivot_wider(names_from = col, values_from = val) %>% # 确保A列在最前面 select(A, everything()) print(result)
运行后会得到你需要的结果:保留A列,仅输出xyz2 = xyz2 - xyz1、xyz3 = xyz3 - xyz2、abc2 = abc2 - abc1这类有前序编号支持的计算列,像abb3、acc4因为没有对应前序项,不会出现在最终结果里。
内容的提问来源于stack exchange,提问作者GiulioGCantone
相关产品推荐
相关产品推荐

