为非 NA 值的运行创建组编号

Qui*_*ten 5 r run-length-encoding dataframe dplyr

我有以下数据框 df (dput如下):

> df
   id value
1   1     1
2   2     3
3   3     2
4  NA     1
5  NA     3
6   8     4
7   9     2
8  10     1
9  NA     1
10 NA     3
11 15     2
12 16     1
13 NA     3
14 NA     4
15 NA     2
16 20     1
17 21     1
18 22     3
19 NA     2
20 NA     1
21 NA     3
22 66     4
23 67     2
24 68     1
Run Code Online (Sandbox Code Playgroud)

对于每次连续运行的非NA“id”,我想创建一个唯一的组 ID(示例中的变量“id2”)。对于NA介于两者之间的情况,“id2”应该是NA

在示例中,第一次运行的非NA“id”(1、2 和 3)应全部属于组 1 (id2 = 1)。第NA4-5 行应该有 id2 = NA。第二次运行的非NA“id”(8、9、10)应具有 id2 = 2,依此类推。

所需的输出应如下所示:

   id value id2
1   1     1   1
2   2     3   1
3   3     2   1
4  NA     1  NA
5  NA     3  NA
6   8     4   2
7   9     2   2
8  10     1   2
9  NA     1  NA
10 NA     3  NA
11 15     2   3
12 16     1   3
13 NA     3  NA
14 NA     4  NA
15 NA     2  NA
16 20     1   4
17 21     1   4
18 22     3   4
19 NA     2  NA
20 NA     1  NA
21 NA     3  NA
22 66     4   5
23 67     2   5
24 68     1   5
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,id2显示了我想要的唯一id,用于NA之间的id值。可能NA值后面只有一个,就像 id 的 1、2 和 3 一样。所以我想知道是否有人知道如何为 之间的值创建唯一的 ID NA


dput的 df:

df <- structure(list(id = c(1, 2, 3, NA, NA, 8, 9, 10, NA, NA, 15, 
16, NA, NA, NA, 20, 21, 22, NA, NA, NA, 66, 67, 68), value = c(1, 
3, 2, 1, 3, 4, 2, 1, 1, 3, 2, 1, 3, 4, 2, 1, 1, 3, 2, 1, 3, 4, 
2, 1)), class = "data.frame", row.names = c(NA, -24L))
Run Code Online (Sandbox Code Playgroud)

bre*_*auv 7

这是一种可能性,也许不是最有效的:

  1. id找到 valid和 an之间的转换NA1每次我们有一个 which 时,都会给你一个ida NA,但前一个是有效的。
  2. 进行累计总和
  3. NA在需要的地方添加
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
df <- structure(list(id = c(1, 2, 3, NA, NA, 8, 9, 10, NA, NA, 15, 
                            16, NA, NA, NA, 20, 21, 22, NA, NA, NA, 66, 67, 68), value = c(1, 
                                                                                           3, 2, 1, 3, 4, 2, 1, 1, 3, 2, 1, 3, 4, 2, 1, 1, 3, 2, 1, 3, 4, 
                                                                                           2, 1)), class = "data.frame", row.names = c(NA, -24L))

df |> 
  mutate(
    id2 = as.numeric(is.na(id) & !is.na(lag(id))),
    id2 = cumsum(id2) + 1,
    id2 = ifelse(is.na(id), NA, id2)
  )
#>    id value id2
#> 1   1     1   1
#> 2   2     3   1
#> 3   3     2   1
#> 4  NA     1  NA
#> 5  NA     3  NA
#> 6   8     4   2
#> 7   9     2   2
#> 8  10     1   2
#> 9  NA     1  NA
#> 10 NA     3  NA
#> 11 15     2   3
#> 12 16     1   3
#> 13 NA     3  NA
#> 14 NA     4  NA
#> 15 NA     2  NA
#> 16 20     1   4
#> 17 21     1   4
#> 18 22     3   4
#> 19 NA     2  NA
#> 20 NA     1  NA
#> 21 NA     3  NA
#> 22 66     4   5
#> 23 67     2   5
#> 24 68     1   5
Run Code Online (Sandbox Code Playgroud)

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