基于两DataFrame的value列最大值选行并标记来源(适配大数据量)
问题描述
现有两个行数、列数完全一致的DataFrame(示例数据如下),需创建新DataFrame:每行从两个原DataFrame的对应行中选取value列数值更大的完整行,同时新增一列标记该行来自df_1还是df_2。实际数据量约20万行,需最优实现方法。
示例数据
DataFrame 1
card value cat1 cat2 cat3 <chr> <dbl> <dbl> <dbl> <dbl> 1 A 10 1 2 3 2 A 20 4 5 6 3 B 30 7 8 9 4 A 40 10 11 12
DataFrame 2
card value cat1 cat2 cat3 <chr> <dbl> <dbl> <dbl> <dbl> 1 C 11 13 14 15 2 C 19 16 17 18 3 A 35 19 20 21 4 B 45 22 23 24
期望结果
card value cat1 cat2 cat3 source <chr> <dbl> <dbl> <dbl> <dbl> <chr> 1 C 11 13 14 15 df_2 2 A 20 4 5 6 df_1 3 A 35 19 20 21 df_2 4 B 45 22 23 24 df_2
数据结构定义
df_1 <- structure(list(card = c("A", "A", "B", "A"), value = c(10, 20, 30, 40), cat1 = c(1, 4, 7, 10), cat2 = c(2, 5, 8, 11), cat3 = c(3, 6, 9, 12)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L)) df_2 <- structure(list(card = c("C", "C", "A", "B"), value = c(11, 19, 35, 45), cat1 = c(13, 16, 19, 22), cat2 = c(14, 17, 20, 23), cat3 = c(15, 18, 21, 24)), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -4L))
解决方案
针对20万行大数据量,推荐以下高效实现方式:
1. data.table(最优性能)
data.table在处理大规模数据时速度优势显著,操作如下:
library(data.table) # 转换为data.table格式 dt1 <- as.data.table(df_1) dt2 <- as.data.table(df_2) # 添加来源标记 dt1[, source := "df_1"] dt2[, source := "df_2"] # 逐行比较value,选择数值更大的行 result <- rbind(dt1, dt2)[, .SD[which.max(value)], by = .I]
2. dplyr(简洁易读)
若习惯tidyverse生态,dplyr的实现兼顾效率与可读性:
library(dplyr) result <- bind_rows(df_1 %>% mutate(source = "df_1"), df_2 %>% mutate(source = "df_2")) %>% group_by(row_number()) %>% slice_max(value, n = 1) %>% ungroup()
3. Base R(无依赖)
无需加载第三方包时,可通过向量操作实现:
# 生成来源标记向量 source_vec <- ifelse(df_1$value >= df_2$value, "df_1", "df_2") # 逐列选取对应行的数据 result <- data.frame( card = ifelse(source_vec == "df_1", df_1$card, df_2$card), value = pmax(df_1$value, df_2$value), cat1 = ifelse(source_vec == "df_1", df_1$cat1, df_2$cat1), cat2 = ifelse(source_vec == "df_1", df_1$cat2, df_2$cat2), cat3 = ifelse(source_vec == "df_1", df_1$cat3, df_2$cat3), source = source_vec )
补充说明
- 当两行
value相等时,以上方法均默认优先选择df_1的行,若需调整优先级,修改判断逻辑即可。 - 数据量20万行时,data.table执行速度最快,base R次之,dplyr适合在tidyverse工作流中使用。
内容的提问来源于stack exchange,提问作者ixodid
相关产品推荐
相关产品推荐

