如何按Sample分组,基于Start/End时间计算衍生列Calc?
问题:按分组计算指定时间点的Measure比值
现有如下R语言DataFrame:
df <- data.frame(sample = c('A','A','A','A','A','B','B','B','B','B'), measure = c(20,30,40,60,60,20,60,50,40,10), time = c(1,2,3,4,5,3,4,5,6,7), start = c(1,1,1,1,1,3,3,3,3,3), end = c(4,4,4,4,4,6,6,6,6,6))
输出结构为:
sample measure time start end 1 A 20 1 1 4 2 A 30 2 1 4 3 A 40 3 1 4 4 A 60 4 1 4 5 A 60 5 1 4 6 B 20 3 3 6 7 B 60 4 3 6 8 B 50 5 3 6 9 B 40 6 3 6 10 B 10 7 3 6
需求:新增名为calc的列,计算每个sample分组内,time等于end时的measure值除以time等于start时的measure值。
解决方案(dplyr 方法)
利用group_by按sample分组后,提取组内对应start和end时间点的measure值,再计算比值:
library(dplyr) df_result <- df %>% group_by(sample) %>% mutate( # 提取组内time等于start的measure值(每组start值统一,取第一个即可) start_measure = measure[time == start[1]], # 提取组内time等于end的measure值 end_measure = measure[time == end[1]], # 计算比值 calc = end_measure / start_measure ) %>% ungroup()
解决方案(Base R 方法)
无需加载包,通过tapply提取分组对应值后匹配到原数据:
# 获取每个sample分组的start对应measure值 start_vals <- tapply(df$measure, df$sample, function(x) { group_rows <- df$sample == names(x) x[df$time[group_rows] == df$start[group_rows][1]] }) # 获取每个sample分组的end对应measure值 end_vals <- tapply(df$measure, df$sample, function(x) { group_rows <- df$sample == names(x) x[df$time[group_rows] == df$end[group_rows][1]] }) # 将比值添加到原数据的calc列 df$calc <- unlist(mapply(function(s) end_vals[[s]] / start_vals[[s]], df$sample))
最终结果
两种方法都会得到如下输出:
sample measure time start end calc 1 A 20 1 1 4 3 2 A 30 2 1 4 3 3 A 40 3 1 4 3 4 A 60 4 1 4 3 5 A 60 5 1 4 3 6 B 20 3 3 6 2 7 B 60 4 3 6 2 8 B 50 5 3 6 2 9 B 40 6 3 6 2 10 B 10 7 3 6 2
内容的提问来源于stack exchange,提问作者yixu501
相关产品推荐
相关产品推荐

