在R中基于区间DataFrame计算多行指定列均值
基于位置区间计算DataFrame列均值
现有两个R语言DataFrame:
- df1包含
ID、POSITION、S1、S2字段,已按ID和POSITION排序:
df1=read.table(text="ID POSITION S1 S2 1 1 10 10 1 2 20 0 1 3 10 0 1 4 20 0 1 5 10 50 2 1 10 0 2 2 20 10 2 3 20 10 2 4 20 10 2 5 20 10", header=TRUE)
- df2为每个ID对应的位置区间数据,包含
ID、POSITION_START、POSITION_END字段:
df2=read.table(text="ID POSITION_START POSITION_END 1 1 3 1 4 5 2 1 5", header=TRUE)
需要根据df2的ID和位置区间,计算df1中对应范围内S1和S2的均值,得到目标DataFrame df3:
df3=read.table(text="ID POSITION_START POSITION_END S1 S2 1 1 3 13.33 3.3 1 4 5 15 25 2 1 5 18 8", header=TRUE)
方法一:使用dplyr逐行计算
适合熟悉tidyverse语法的场景,逐行处理df2的区间条件,匹配df1中对应数据并计算均值:
library(dplyr) df3 <- df2 %>% rowwise() %>% mutate( S1 = mean(df1$S1[df1$ID == ID & df1$POSITION >= POSITION_START & df1$POSITION <= POSITION_END]), S2 = mean(df1$S2[df1$ID == ID & df1$POSITION >= POSITION_START & df1$POSITION <= POSITION_END]) ) %>% ungroup() # 可选:格式化小数位数以匹配目标结果 df3 <- df3 %>% mutate( S1 = round(S1, 2), S2 = round(S2, 1) )
方法二:使用data.table非等值连接
适合大数据量场景,非等值连接的方式效率更高:
library(data.table) # 转换为data.table格式 setDT(df1) setDT(df2) # 非等值连接并按区间分组计算均值 df3 <- df2[df1, on = .(ID, POSITION_START <= POSITION, POSITION_END >= POSITION), .(S1 = mean(S1), S2 = mean(S2)), by = .EACHI] # 调整列顺序并格式化小数 setcolorder(df3, c("ID", "POSITION_START", "POSITION_END", "S1", "S2")) df3[, `:=`(S1 = round(S1, 2), S2 = round(S2, 1))]
两种方法均可得到符合要求的df3,其中data.table方案在数据量较大时性能优势更明显。
内容的提问来源于stack exchange,提问作者Gabriel G.
相关产品推荐
相关产品推荐

