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

R语言分组数据处理:如何筛选每组的中间行?

Hey there! Let's figure out how to grab the middle row for each group in your data frame.

First, let's recap your setup to make sure we're on the same page:
Your original data frame is defined as:

df <- data.frame(id=c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3), x=c(1,2,3,3,5,1,4,3,1,2,8,9,3,1,0))

And you already know how to get the first row per group with:

df %>% group_by(id) %>% filter(row_number()==1)

Getting the middle row per group

The key here is to calculate the middle position using the total number of rows in each group (we can get that with n() in dplyr).

1. For groups with an odd number of rows (like your example, 5 rows per group)

Since each of your groups has 5 rows, the middle row is the 3rd one. We can calculate this position with ceiling(n()/2) (or floor(n()/2) + 1—both give the same result for odd counts).

You can use either filter() or the more concise slice() function:

library(dplyr)

# Using filter()
df %>% 
  group_by(id) %>% 
  filter(row_number() == ceiling(n()/2))

# Or using slice() (cleaner for row selection)
df %>% 
  group_by(id) %>% 
  slice(ceiling(n()/2))

Running either of these will return the 3rd row for each group:

# A tibble: 3 × 2
# Groups:   id [3]
     id     x
  <dbl> <dbl>
1     1     3
2     2     3
3     3     3

2. Handling groups with even numbers of rows

If your data had groups with even row counts (e.g., 4 rows), you might want to choose either the upper-middle or lower-middle row:

  • To get the lower-middle row (2nd row in a 4-row group): use floor(n()/2)
  • To get the upper-middle row (3rd row in a 4-row group): use floor(n()/2) + 1
  • To get both middle rows: use row_number() %in% c(floor(n()/2), floor(n()/2)+1)

Example for even-row groups:

# Sample data with a 4-row group
df_even <- data.frame(id=c(1,1,1,1,2,2,2,2,2), x=c(10,20,30,40,5,6,7,8,9))

# Get upper-middle row for each group
df_even %>% 
  group_by(id) %>% 
  slice(floor(n()/2) + 1)

Why this works

  • n() returns the total number of rows in the current group
  • ceiling() and floor() adjust the division result to get the correct integer row position
  • slice() is designed for selecting rows by position, making the code more readable than using filter() with row_number()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:39:33