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

基于列唯一值分组行:生成含Doos全值的4组数据求助

问题:按指定规则重新排列数据框行

我有如下数据框df:

structure(list(Donorcode = c("406A001", "406A002", "406A003", 
"406A004", "406A003", "406A008", "406A009", "406A007"), Doos = c(1, 
1, 1, 1, 2, 2, 2, 2), `Leeftijd T0` = c(70, 73, 79, 75, 70, 73, 
79, 75), Instituut = c("Spaarne ziekenhuis", "Spaarne ziekenhuis", 
"Spaarne ziekenhuis", "RIVM", "RIVM", "RIVM", "RIVM", "Spaarne ziekenhuis"
), Datum = structure(c(1567468800, 1567555200, 1567900800, 1567468800, 
1567468800, 1567555200, 1567987200, 1568246400), class = c("POSIXct", 
"POSIXt"), tzone = "UTC")), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -8L))

我需要将数据分为4组,每组都包含Doos列的所有取值,期望输出如下:

Donorcode  Doos `Leeftijd T0` Instituut          Datum              
  <chr>     <dbl>         <dbl> <chr>              <dttm>              
1 406A001       1            70 Spaarne ziekenhuis 2019-09-03 00:00:00
2 406A003       2            70 RIVM               2019-09-03 00:00:00
3 406A003       1            79 Spaarne ziekenhuis 2019-09-08 00:00:00
4 406A009       2            79 RIVM               2019-09-09 00:00:00
5 406A004       1            75 RIVM               2019-09-03 00:00:00
6 406A008       2            73 RIVM               2019-09-04 00:00:00
7 406A002       1            73 Spaarne ziekenhuis 2019-09-04 00:00:00
8 406A007       2            75 Spaarne ziekenhuis 2019-09-12 00:00:00

尝试使用dplyr::group_by(df, Doos, Instituut)得到的结果不符合需求,当前输出:

dplyr::group_by(df, Doos, Instituut)
# A tibble: 8 × 5
# Groups:   Doos, Instituut [4]
  Donorcode  Doos `Leeftijd T0` Instituut          Datum              
  <chr>     <dbl>         <dbl> <chr>              <dttm>              
1 406A001       1            70 Spaarne ziekenhuis 2019-09-03 00:00:00
2 406A002       1            73 Spaarne ziekenhuis 2019-09-04 00:00:00
3 406A003       1            79 Spaarne ziekenhuis 2019-09-08 00:00:00
4 406A004       1            75 RIVM               2019-09-03 00:00:00
5 406A003       2            70 RIVM               2019-09-03 00:00:00
6 406A008       2            73 RIVM               2019-09-04 00:00:00
7 406A009       2            79 RIVM               2019-09-09 00:00:00
8 406A007       2            75 Spaarne ziekenhuis 2019-09-12 00:00:00

希望能实现支持多列同时分组的函数(比如加入Instituut列进行分组)。


解决方案

核心思路

先根据目标分组列(如Leeftijd T0)和需要分散的列(Doos)创建子分组,给每个子分组内的记录分配行号,最后按行号和Doos排序,实现每组交替包含不同Doos值的效果。

基础实现(按Leeftijd T0分组)

library(dplyr)

df %>%
  # 按Leeftijd T0和Doos分组,给每组内的记录分配序号
  group_by(`Leeftijd T0`, Doos) %>%
  mutate(row_id = row_number()) %>%
  ungroup() %>%
  # 按行号、Doos排序,实现交替排列
  arrange(row_id, Doos) %>%
  # 移除临时行号列
  select(-row_id)

通用分组重排函数

如果需要支持自定义多列分组,可使用以下函数:

rearrange_groups <- function(data, group_cols, spread_col) {
  data %>%
    group_by(across(c({{group_cols}}, {{spread_col}}))) %>%
    mutate(row_id = row_number()) %>%
    ungroup() %>%
    arrange(row_id, {{spread_col}}) %>%
    select(-row_id)
}

# 示例1:按Leeftijd T0分组,分散Doos列
rearrange_groups(df, `Leeftijd T0`, Doos)

# 示例2:同时按Leeftijd T0和Instituut分组,分散Doos列
rearrange_groups(df, c(`Leeftijd T0`, Instituut), Doos)

函数参数说明:

  • data:输入的数据框
  • group_cols:用于分组的列(支持单列或多列向量)
  • spread_col:需要在每组内包含所有取值的列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:06:23