R语言 更新游程ID,但跳过NA

7lrncoxx  于 2023-03-15  发布在  其他
关注(0)|答案(5)|浏览(101)

给定此类数据:

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")
)

我如何更新Sequ的游程ID才能比这样做更有效:

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

注意:虽然我使用的是data.table中的rleid,但我正在寻找一个tidyverse解决方案。

amrnrhlw

amrnrhlw1#

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))))

还有:

df %>%
  mutate(Sequ_0 =  replace(Q, !is.na(Q), consecutive_id(na.omit(Sequ))))
z18hc3ub

z18hc3ub2#

使用 consecutive_id 获取id,然后排除NA,转换为因子,然后再转换回数值以获得序列号:

library(dplyr) # dplyr_1.1.0 - consecutive_id

df %>% 
  mutate(id = as.numeric(as.factor(
    if_else(is.na(Sequ), NA, consecutive_id(Sequ)))))
#    ID Sequ    Q id
# 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
ego6inou

ego6inou3#

下面是将arrangeconsecutive_id一起使用的另一个选项:

library(dplyr) #dplyr >= 1.1.0
df %>% 
  arrange(Q) %>% 
  mutate(Sequ_0 =  consecutive_id(Sequ),
         Sequ_0 = ifelse(is.na(Sequ), NA_real_, Sequ_0)) %>% 
  arrange(ID)

   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
webghufk

webghufk4#

可以选择将matchunique一起使用来创建如下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

创建于2023年3月9日,使用reprex v2.0.2

p1tboqfb

p1tboqfb5#

以R为基:

transform(df, seq0 = with(rle(Sequ), 
          rep(`[<-`(values, !is.na(values), seq(na.omit(values))), lengths)))

   ID Sequ    Q seq0
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

回到基础:

a <- rle(df$Sequ)
a$values[!is.na(a$values)] <- seq_along(na.omit(a$values))
cbind(df, sequ_0 = inverse.rle(a))

   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

相关问题