按单倍型分组计算数据框中相邻世代均值的百分比变化
按单倍型分组计算数据框中相邻世代均值的百分比变化
看起来你已经走对了大半路——你已经用group_by(hap)实现了按单倍型分组,也知道用lag()来获取前一世代的avg值,现在只差把绝对差值转换成百分比变化的最终公式啦!
问题回顾
你需要的百分比变化核心公式是:
((当前世代avg - 前一世代avg) / 前一世代avg) × 100
第一行(每个单倍型的G1)因为没有前序世代,所以百分比变化为0,你设置的default = avg[1]已经完美解决了第一行的默认值问题。
完整解决方案代码
library(dplyr) # 你的原始数据框 gens_avg <- structure(list(hap = c("hap1", "hap1", "hap1", "hap1", "hap2", "hap2", "hap2", "hap2"), gen = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), levels = c("G1", "G2", "G3", "G4"), class = "factor"), sum = c(1924959, 895814, 2344706, 2873530, 2165959, 845385, 2431160, 2189315), `# of ind` = c(1720L, 860L, 3010L, 4300L, 1720L, 860L, 3010L, 4300L), avg = c(1119.16220930233, 1041.64418604651, 778.972093023256, 668.262790697674, 1259.27848837209, 983.005813953488, 807.694352159468, 509.143023255814)), row.names = c(NA, -8L ), class = "data.frame") # 计算百分比变化 gens_avg <- gens_avg %>% group_by(hap) %>% mutate( `% change` = ((avg - lag(avg, default = avg[1])) / lag(avg, default = avg[1])) * 100 ) %>% ungroup() # 可选:如果后续不需要分组状态,取消分组更方便 # 查看完整结果 print(gens_avg, digits = 10)
结果验证
运行后你会得到和你预期完全匹配的数值:
- hap1 G2的
% change为≈-6.881143878 - hap1 G3的
% change为≈-25.23992322 - hap2 G2的
% change为≈-21.92216044
完全符合你给出的目标输出。
可选优化:控制小数位数
如果想让结果更整洁,可以用round()函数指定保留的小数位数,比如保留8位小数:
mutate( `% change` = round(((avg - lag(avg, default = avg[1])) / lag(avg, default = avg[1])) * 100, 8) )
内容来源于stack exchange
相关产品推荐
相关产品推荐

