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

如何在dbplyr查询的summarise函数中获取分组首行与末行

在dbplyr分组查询中获取首行/末行的替代方案

问题

本地dplyr中可以用head()在summarise里提取分组后的首行,但dbplyr无法将head()转换为SQL语句,执行时会报错no such function: head。需要用数据库兼容的方法实现分组后取首行和末行。

解决方案

1. 提取单个字段的首/末值:用first()和last()

dbplyr原生支持first()和last()函数,它们会被转换为对应的SQL聚合逻辑,但必须先排序保证行顺序符合预期:

library(tidyverse)
library(DBI)
library(dbplyr)

# 初始化测试连接与表
con <- dbConnect(RSQLite::SQLite(), "")
dbWriteTable(con, "mtcars", mtcars)

# 分组取mpg字段的首行值
con %>%
  tbl("mtcars") %>%
  arrange(cyl, mpg) %>%  # 先按分组键cyl排序,再按目标字段mpg排序(可选,确保顺序)
  group_by(cyl) %>%
  summarise(first_mpg = first(mpg)) %>%
  collect()

# 分组取mpg字段的末行值
con %>%
  tbl("mtcars") %>%
  arrange(cyl, mpg) %>%
  group_by(cyl) %>%
  summarise(last_mpg = last(mpg)) %>%
  collect()

2. 提取整行的首/末数据:窗口函数+filter

如果需要获取分组后首行/末行的完整数据,用row_number()窗口函数给分组内的行编号,再筛选目标行:

# 提取分组首行整行数据
con %>%
  tbl("mtcars") %>%
  arrange(cyl, mpg) %>%
  group_by(cyl) %>%
  mutate(row_num = row_number()) %>%
  filter(row_num == 1) %>%
  ungroup() %>%
  collect()

# 提取分组末行整行数据
con %>%
  tbl("mtcars") %>%
  arrange(cyl, desc(mpg)) %>%  # 倒序排序后,第一行即为原顺序的末行
  group_by(cyl) %>%
  mutate(row_num = row_number()) %>%
  filter(row_num == 1) %>%
  ungroup() %>%
  collect()

3. 简洁写法:用slice_head()/slice_tail()(dbplyr 1.0.0+)

如果你的dbplyr版本在1.0.0及以上,可以直接用slice_head()和slice_tail(),语法更直观:

# 分组取首行
con %>%
  tbl("mtcars") %>%
  arrange(cyl, mpg) %>%
  group_by(cyl) %>%
  slice_head(n = 1) %>%
  ungroup() %>%
  collect()

# 分组取末行
con %>%
  tbl("mtcars") %>%
  arrange(cyl, mpg) %>%
  group_by(cyl) %>%
  slice_tail(n = 1) %>%
  ungroup() %>%
  collect()

重要提示

  • 所有方法都必须先执行arrange(),数据库返回的行默认是无序的,不排序的话首末行结果完全不可靠。
  • first()/last()适合只需要单个字段的场景,slice系列或窗口函数适合获取整行数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:55:06