tidyverse:在 R 中创建自定义分组变量

问题描述 投票:0回答:1

我想根据 GT 的值创建一个具有特定条件的组变量。 如果 GT 是“I”,它应该生成不同的组号。如果 GT 为“G”,则应适用以下规则:

  1. 对于前四个连续的“G”,分配相同的组号,对于接下来的四个连续的“G”,分配下一个组号。
  2. 如果有五个连续的“G”,则为前三个“G”分配相同的组号,为其余两个“G”分配不同的组号。

我的尝试:

library(tidyverse)
df1 <- 
  data.frame(
   GT = c(rep("G", 9), rep("I", 2), rep("G", 2), rep("I", 1))
  )

df2 <- 
  df1 %>%
  mutate(
      grp1 = case_when(
         GT == "I" ~ row_number()
      , .default = consecutive_id(GT)
      )
         ) %>%
  group_by(GT, grp1) %>%
  mutate(count = n()) %>%
  ungroup() %>% 
  mutate(
    grp2 = case_when(
        GT == "G" & count %/% 4 > 0  ~ row_number() %/% 5 + row_number(1)
      , .default = grp1
    )
  , grp3 = case_when(
        GT == "G"~ (cumsum(GT == "G") - 1) %/% 4 + 1
      , .default = grp1 
        )
      )

df2
#> # A tibble: 14 × 5
#>    GT     grp1 count  grp2  grp3
#>    <chr> <int> <int> <dbl> <dbl>
#>  1 G         1     9     1     1
#>  2 G         1     9     1     1
#>  3 G         1     9     1     1
#>  4 G         1     9     1     1
#>  5 G         1     9     2     2
#>  6 G         1     9     2     2
#>  7 G         1     9     2     2
#>  8 G         1     9     2     2
#>  9 G         1     9     2     3
#> 10 I        10     1    10    10
#> 11 I        11     1    11    11
#> 12 G         3     2     3     3
#> 13 G         3     2     3     3
#> 14 I        14     1    14    14

组变量

grp2
非常接近要求。但是,我希望
df2[8:9, 4]
应该具有与
df2[5:7, 4]
不同的组号。请任何提示!

r dplyr tidyverse grouping
1个回答
0
投票

我按照您创建

grp1
列的方法进行操作,但我使用
rep()
以及一些额外的模算术来计算
grp2
列,这使我们能够制作最终的“3+2”组。

因此,我必须从

case_when()
切换到
if...else
并添加一些对
unique()
的调用,以避免回收
if
条件下的值。

library(tidyverse)
df1 <- 
  data.frame(
    GT = c(rep("G", 9), rep("I", 2), rep("G", 2), rep("I", 1))
  )

want <- df1 %>%
  mutate(
    grp1 = case_when(
      GT == "I" ~ row_number(),
      .default = consecutive_id(GT)
    )
  ) %>%
  mutate(
    grp2 = if(unique(GT) == "I" | unique(n() %/% 4) < 1) {
      grp1
    } else if(unique(n() %% 4) == 1) {
      c(rep(1:(n() %/% 4 - 1), each = 4), rep(n() %/% 4, 3), rep(n() %/% 4 + 1, 2))
    } else {
      c(rep(1:n() %/% 4, each = 4), rep(n() %/% 4 + 1, each = n() %% 4))
    } ,
    .by = c(GT, grp1)
  ) %>%
  mutate(group = consecutive_id(GT, grp2)) %>%
  select(-grp1, -grp2)

want
#>    GT group
#> 1   G     1
#> 2   G     1
#> 3   G     1
#> 4   G     1
#> 5   G     2
#> 6   G     2
#> 7   G     2
#> 8   G     3
#> 9   G     3
#> 10  I     4
#> 11  I     5
#> 12  G     6
#> 13  G     6
#> 14  I     7

创建于 2024-05-25,使用 reprex v2.1.0

© www.soinside.com 2019 - 2024. All rights reserved.