如何高效实现基于重复Key与日期提取DataFrame指定列值
高效处理按Key聚合的DataFrame需求
我有一个包含4列的DataFrame:
- 第一列(
key):每个值恰好出现2次 - 第二列:日期类型
- 第三列(
val1)、第四列(val2):布尔值
需求:按key去重,val1取对应key最早日期的取值,val2取对应key最晚日期的取值。
示例数据集
keys <- c("A","A","B","B","C","C") dates <- as.POSIXct(c("2021-01-01", "2021-02-02","2021-03-03", "2021-04-04", "2021-05-05", "2021-06-06")) vals1 <- c("T","F","T","F","F","F") vals2 <- c("F","T","T","T","F","T") df <- data.frame(key = keys, date = dates, val1 = vals1, val2 = vals2)
生成的DataFrame:
> df key date val1 val2 1 A 2021-01-01 T F 2 A 2021-02-02 F T 3 B 2021-03-03 T T 4 B 2021-04-04 F T 5 C 2021-05-05 F F 6 C 2021-06-06 F T
原低效实现(for循环)
for (i in 1:nrow(df)){ val1 <- df %>% filter(key == df$key[i]) %>% slice(which.min(date)) %>% ungroup() %>% select(val1) val2 <- df %>% filter(key == df$key[i]) %>% slice(which.max(date)) %>% ungroup() %>% select(val2) df$val1[df$key == df$key[i]] <- val1$val1 df$val2[df$key == df$key[i]] <- val2$val2 } df <- df[!duplicated(df$key),c("key","val1","val2")] > df key val1 val2 1 A T T 3 B T T 5 C F T
该方法处理4万行以上的大型数据集时效率极低,急需更高效的实现方式。
高效解决方案
方法1:使用dplyr分组聚合(向量化操作)
利用dplyr的分组函数直接对每个key组计算所需值,避免循环中的重复筛选:
library(dplyr) result_df <- df %>% group_by(key) %>% summarize( val1 = val1[which.min(date)], # 取当前key最早日期的val1 val2 = val2[which.max(date)] # 取当前key最晚日期的val2 ) %>% ungroup() > result_df # A tibble: 3 × 3 key val1 val2 <chr> <chr> <chr> 1 A T T 2 B T T 3 C F T
方法2:使用data.table(极致性能)
data.table在处理大规模数据集时性能优势明显,适合持续增长的数据集:
library(data.table) setDT(df) # 将data.frame转换为data.table格式 result_dt <- df[, .( val1 = val1[which.min(date)], val2 = val2[which.max(date)] ), by = key] > result_dt key val1 val2 1: A T T 2: B T T 3: C F T
这两种方案均为向量化操作,避免了循环中的重复数据筛选,处理大型数据集时速度会有数量级的提升。
内容的提问来源于stack exchange,提问作者BillyBouw
相关产品推荐
相关产品推荐

