library(tidyverse)
df <- data.frame(x=rep(c('A','B'), times=c(5,15)), y=1:20)
我正在尝试将
df
分割成大小相似的块,并且限制为 x
中的每个组也必须在 n
分割中表示并平均分割。例如如果 n = 3
:
$`1`
x y
1 A 1
2 A 2
3 B 6
4 B 7
5 B 8
6 B 9
7 B 10
$`2`
x y
1 A 3
2 A 4
3 B 11
4 B 12
5 B 13
6 B 14
7 B 15
$`3`
x y
1 A 5
2 B 16
3 B 17
4 B 18
5 B 19
6 B 20
对于 n=3,组
A
可以分为 [2,2,1] 的块,而组 B
可以分为 [5,5,5] 的块
我尝试过:
n = 3
df %>% group_by(x) %>% split(., cut(seq_along(.), n, labels = FALSE))
但这只会产生两个分裂
我认为您使用
cut
的做法是正确的。只需确保 n + 1
中的每个组都有 x
中断,这些中断根据行号占总组的比例进行分割。
n <- 3
df %>%
mutate(group = cut((row_number() - 1)/n(),
breaks = seq(0, 1, length = n + 1),
labels = seq(n),
include.lowest = TRUE,
right = FALSE),
.by = x) %>%
{split(.[-3], .[3])}
#> $`1`
#> x y
#> 1 A 1
#> 2 A 2
#> 6 B 6
#> 7 B 7
#> 8 B 8
#> 9 B 9
#> 10 B 10
#>
#> $`2`
#> x y
#> 3 A 3
#> 4 A 4
#> 11 B 11
#> 12 B 12
#> 13 B 13
#> 14 B 14
#> 15 B 15
#>
#> $`3`
#> x y
#> 5 A 5
#> 16 B 16
#> 17 B 17
#> 18 B 18
#> 19 B 19
#> 20 B 20
分割数据集时,我喜欢在 tidyverse 中使用嵌套的
data.frames
。这是使用模运算符 %%
分割数据的一种方法:
library(tidyverse)
df |>
mutate(split = row_number() %% 3,
.by = x) |>
nest_by(split)
#> # A tibble: 3 × 2
#> # Rowwise: split
#> split data
#> <dbl> <list<tibble[,2]>>
#> 1 0 [6 × 2]
#> 2 1 [7 × 2]
#> 3 2 [7 × 2]
来自OP的数据
df <- data.frame(x=rep(c('A','B'), times=c(5,15)), y=1:20)
创建于 2023 年 12 月 11 日,使用 reprex v2.0.2