更新游程 ID 但跳过 NA

Chr*_*ann 6 r dplyr

给定此类数据:

df <- data.frame(
  ID = 1:10,
  Sequ = c(NA, 44,44, NA, NA, 33,33,33, 5,5),
  Q = c(NA, "q1","q1", NA, NA, "q2","q2","q2", "q2","q2")
)
Run Code Online (Sandbox Code Playgroud)

如何比这样做更有效地更新游程 ID :Sequ

library(dplyr)
library(data.table)
left_join(df, df %>%
  filter(!is.na(Sequ)) %>%
  mutate(Sequ_0 = rleid(Sequ))) %>%
  select(-Sequ)
   ID    Q Sequ_0
1   1 <NA>     NA
2   2   q1      1
3   3   q1      1
4   4 <NA>     NA
5   5 <NA>     NA
6   6   q2      2
7   7   q2      2
8   8   q2      2
9   9   q2      3
10 10   q2      3
Run Code Online (Sandbox Code Playgroud)

注意:虽然我正在使用rleidfrom,data.table但我正在寻找tidyverse解决方案。

Ony*_*mbu 5

df %>%
   mutate(Sequ_0 = dense_rank(NA^is.na(Q)*consecutive_id(Sequ)))

   ID Sequ    Q Sequ_0
1   1   NA <NA>     NA
2   2   44   q1      1
3   3   44   q1      1
4   4   NA <NA>     NA
5   5   NA <NA>     NA
6   6   33   q2      2
7   7   33   q2      2
8   8   33   q2      2
9   9    5   q2      3
10 10    5   q2      3

df %>%
   mutate(Sequ_0 = dense_rank(`is.na<-`(consecutive_id(Sequ), is.na(Q))))
Run Code Online (Sandbox Code Playgroud)

还:

df %>%
  mutate(Sequ_0 =  replace(Q, !is.na(Q), consecutive_id(na.omit(Sequ))))
Run Code Online (Sandbox Code Playgroud)


Qui*_*ten 1

match可以使用with选项unique来创建 ID,如下所示:

library(tidyverse)
df %>%
  left_join(., df %>%
              drop_na() %>%
              mutate(Sequ_0 = match(Sequ, unique(Sequ))))
#> Joining with `by = join_by(ID, Sequ, Q)`
#>    ID Sequ    Q Sequ_0
#> 1   1   NA <NA>     NA
#> 2   2   44   q1      1
#> 3   3   44   q1      1
#> 4   4   NA <NA>     NA
#> 5   5   NA <NA>     NA
#> 6   6   33   q2      2
#> 7   7   33   q2      2
#> 8   8   33   q2      2
#> 9   9    5   q2      3
#> 10 10    5   q2      3
Run Code Online (Sandbox Code Playgroud)

创建于 2023-03-09,使用reprex v2.0.2