You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于两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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 07:20:36