R 按系数和有序行位置分组数据

R 按系数和有序行位置分组数据,r,tidyverse,R,Tidyverse,以下代码 set.seed(123) data <- runif(20) dummy <- as.data.frame(data) dummy <- dummy %>% mutate(category = factor(case_when(data < 0.5 ~ 'A', data >= 0.5 ~ 'B'))) 我的问题: 我想创建一个名为packet的新列,该列根据类别和表中

以下代码

set.seed(123)
data <- runif(20) 
dummy <- as.data.frame(data)
dummy <- dummy %>% mutate(category = factor(case_when(data < 0.5 ~ 'A', 
                                    data >= 0.5  ~ 'B')))
我的问题:

我想创建一个名为
packet
的新列,该列根据类别和表中的有序位置创建一个新分组。它应该将每个类别的第一个
packet\u size
行标记为
packet\u num
,然后下一个
packet\u size
行应该标记为
packet\u num+1
,依此类推

例如,对于
数据包大小=2
,前10行应如下所示:

        data category
1  0.2875775        A
2  0.7883051        B
3  0.4089769        A
4  0.8830174        B
5  0.9404673        B
6  0.0455565        A
7  0.5281055        B
8  0.8924190        B
9  0.5514350        B
10 0.4566147        A
. ...              ...
        data category packet
1  0.2875775        A      1
2  0.7883051        B      1
3  0.4089769        A      1
4  0.8830174        B      1
5  0.9404673        B      2
6  0.0455565        A      2
7  0.5281055        B      2
8  0.8924190        B      3
9  0.5514350        B      3
10 0.4566147        A      2
. ...              ...
如果我将
dummy
筛选为单个
类别
,那么我可以在子集上运行以下操作,这似乎是可行的:

dummy <- dummy %>% add_column(packet=1L)
filtered_dummy <- dummy %>% filter(category=='A')

packet_size <- 2
packet_num <- 1
row_count <- 1
for (i in 1:nrow(filtered_dummy)) {
  filtered_dummy[i, "packet"] <- packet_num

  row_count <- row_count + 1
  if (row_count > packet_size) {
      packet_num <- packet_num + 1
      row_count = 1
  }
}
dummy%add\u列(数据包=1L)
已筛选\u虚拟%filter(类别=='A')

packet\u size我们可以创建一个重复序列,每个
类别的
packet\u size
重复一个数字

packet_size <- 2
library(dplyr)

dummy %>%
  group_by(category) %>%
  mutate(packet = rep(seq_len(n()), each = packet_size, length.out = n()))


#    data category packet
#    <dbl> <fct>     <int>
# 1 0.288  A             1
# 2 0.788  B             1
# 3 0.409  A             1
# 4 0.883  B             1
# 5 0.940  B             2
# 6 0.0456 A             2
# 7 0.528  B             2
# 8 0.892  B             3
# 9 0.551  B             3
#10 0.457  A             2
#...
#...
您也可以在base R中实现相同的逻辑:

dummy$packet <- with(dummy, ave(data, category, FUN = function(x)
               rep(seq_along(x), each = packet_size, length.out = length(x))))

dummy$packet另一个选项可以是:

dummy %>%
 group_by(category) %>%
 mutate(packet = ceiling(1:n()/packet_size))

     data category packet
    <dbl> <fct>     <dbl>
 1 0.288  A             1
 2 0.788  B             1
 3 0.409  A             1
 4 0.883  B             1
 5 0.940  B             2
 6 0.0456 A             2
 7 0.528  B             2
 8 0.892  B             3
 9 0.551  B             3
10 0.457  A             2
dummy%>%
组别(类别)%>%
变异(数据包=上限(1:n()/数据包大小))
数据类别分组
1 0.288 A 1
2 0.788 B 1
30.409 A 1
4 0.883 B 1
5 0.940 B 2
6 0.0456 A 2
7 0.528 B 2
8 0.892 B 3
9 0.551 B 3
10 0.457 A 2

我们也可以使用
gl

library(dplyr)
dummy %>%
   group_by(category) %>%
   mutate(packet = as.integer(gl(n(), packet_size, n())))

或使用
数据。表格

library(data.table)
setDT(dummy)[, packet := as.integer(gl(n(), packet_size, n())), category]
library(data.table)
setDT(dummy)[, packet := as.integer(gl(n(), packet_size, n())), category]