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

如何在dbplyr分组mutate时正确使用last()函数?

问题:dbplyr远程计算中按分组排序后获取每组最后一个id的正确实现

背景与需求

现有远程数据表定义如下:

library(dbplyr)
library(dplyr, warn.conflicts = FALSE)
remote_data <- memdb_frame(
  grp = c(2, 2, 2, 1, 3, 1, 1),
  win = c("B", "C", "A", "B", "C", "A", "C"),
  id = c(1,3,5,7,2,4,6),
)

需求:按grp分组,按win排序后,为每组的每一行添加该组排序后的最后一个id(即last_id)。本地拉取数据后计算可得到预期结果:

# 本地计算的预期输出
remote_data %>% 
  collect() %>% 
  arrange(grp, win) %>% 
  group_by(grp) %>% 
  mutate(last_id = last(id)) %>% 
  ungroup()
#> # A tibble: 7 × 4
#>     grp win      id last_id
#>   <dbl> <chr> <dbl>   <dbl>
#> 1     1 A         4       6
#> 2     1 B         7       6
#> 3     1 C         6       6
#> 4     2 A         5       3
#> 5     2 B         1       3
#> 6     2 C         3       3
#> 7     3 C         2       2

但直接用dbplyr远程计算时,结果不符合预期:last_id仅取到当前行的id,而非分组最后一行。尝试window_order()调整排序也未解决问题。

解决方案

方法1:调整窗口框架范围

SQL中LAST_VALUE()默认的窗口范围是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,导致仅能取到当前行之前的值。通过window_frame()将窗口范围扩展到整个分组即可解决:

remote_data %>%
  group_by(grp) %>%
  window_order(win) %>%
  window_frame(-Inf, Inf) %>% # 窗口覆盖分组内所有行
  mutate(last_id = last(id)) %>%
  ungroup() %>%
  arrange(grp, win)

对应的SQL查询会自动添加窗口范围:

SELECT
  *,
  LAST_VALUE(`id`) OVER (
    PARTITION BY `grp` 
    ORDER BY `win` 
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  ) AS `last_id`
FROM `dbplyr_001`
ORDER BY `grp`, `win`

方法2:用first()配合倒序排序

如果不想调整窗口框架,可通过倒序排序后取first(id),等价于原顺序的最后一个值:

remote_data %>%
  group_by(grp) %>%
  window_order(desc(win)) %>% # 按win倒序排列
  mutate(last_id = first(id)) %>% # 倒序后的第一个值即原顺序的最后一个
  ungroup() %>%
  arrange(grp, win)

此方法兼容性更好,部分数据库对窗口框架的支持可能有限,倒序取首值更通用。

方法3:分组聚合后JOIN

先单独计算每组的最后一个id,再通过JOIN合并到原数据,逻辑更直观:

# 先获取每组排序后的最后一个id
last_id_map <- remote_data %>%
  group_by(grp) %>%
  arrange(win) %>%
  slice_tail(n = 1) %>%
  select(grp, last_id = id)

# 关联回原数据
remote_data %>%
  left_join(last_id_map, by = "grp") %>%
  arrange(grp, win)

验证结果

上述三种方法的远程计算结果均与本地拉取后的预期输出一致,可根据个人习惯或数据库特性选择合适方案。

内容的提问来源于stack exchange,提问作者moodymudskipper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 19:05:24