计算 R 中每组连续连续值的长度

Count length of sequential consequtive values per group in R

我有一个包含相应值的数据集,我想知道每个长度出现的次数。 更具体地说,我想找出有多少 id 的序列 运行 来自 1:2、来自 1:3、来自 1:4 等。 只对从 1 开始的序列感兴趣。

在此示例中,id1 将具有来自 1:3 的“完整”序列 运行(因为数字 4 丢失),id2 具有来自 [=25] 的序列 运行 =],id3 有一个序列 运行 来自 1:6,id4 不被计算在内,因为它不是以值 1 开头,而 id 5 有一个序列 运行 来自 1:3 .

所以我们最终得到两个序列直到 3,一个到 5 和一个到 6。

有没有一种聪明的方法来计算这个,而不求助于低效的循环?

示例数据:

data <- data.table( id    = c(1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5),
                    value = c(1,2,3,5,1,2,3,4,5,10,11,1,2,3,4,5,6,2,3,4,5,6,7,8,1,2,3,7))

 > data
    id value
 1:  1     1
 2:  1     2
 3:  1     3
 4:  1     5
 5:  2     1
 6:  2     2
 7:  2     3
 8:  2     4
 9:  2     5
10:  2    10
11:  2    11
12:  3     1
13:  3     2
14:  3     3
15:  3     4
16:  3     5
17:  3     6
18:  4     2
19:  4     3
20:  4     4
21:  4     5
22:  4     6
23:  4     7
24:  4     8
25:  5     1
26:  5     2
27:  5     3
28:  5     7
    id value

利用 dplyr 的一个选项可能是:

data %>%
 group_by(id) %>%
 mutate(rleid = with(rle(c(0, diff(value)) <= 1), rep(seq_along(values), lengths))) %>%
 filter(rleid == 1 & min(value) == 1) %>%
 summarise(value = paste(value, collapse = "")) %>%
 group_by(value) %>%
 summarise(n = n(),
           ids = toString(id))

  value      n ids  
  <chr>  <int> <chr>
1 123        2 1, 5 
2 12345      1 2    
3 123456     1 3    
out <- data[, len0 := rleid(c(TRUE, diff(value) == 1L)), by = .(id) ][
  , .(value1 = first(value), len = .N), by = .(id, len0) ]
out
#       id  len0 value1   len
#    <num> <int>  <num> <int>
# 1:     1     1      1     3
# 2:     1     2      5     1
# 3:     2     1      1     5
# 4:     2     2     10     1
# 5:     2     3     11     1
# 6:     3     1      1     6
# 7:     4     1      2     7
# 8:     5     1      1     3
# 9:     5     2      7     1

演练:

  • 在每个 id 中,创建 len0 以标识增加 1 的步骤
  • idlen0 内,总结第一个值(如果您只想要那些从 1 开始的值,请参见下文)和 length 运行

如果您只想知道那些序列从 1 开始的,请按 value1:

过滤
out[ value1 == 1L, ]
#       id  len0 value1   len
#    <num> <int>  <num> <int>
# 1:     1     1      1     3
# 2:     2     1      1     5
# 3:     3     1      1     6
# 4:     5     1      1     3

(我想你现在只需要 idlen。)

library(data.table)
dt <- data.table( id    = c(1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,5,5,5,5),
                    value = c(1,2,3,5,1,2,3,4,5,10,11,1,2,3,4,5,6,2,3,4,5,6,7,8,1,2,3,7))

dt[, n := seq_len(.N) - value, by = id]
res <- dt[n == 0, .SD[value == max(value)], by = id][, n := NULL]
head(res)
#>    id value
#> 1:  1     3
#> 2:  2     5
#> 3:  3     6
#> 4:  5     3

reprex package (v1.0.0)

于 2021-02-04 创建

这是另一个选项:

data[rowid(id)==value, max(value), id]

输出:

   id V1
1:  1  3
2:  2  5
3:  3  6
4:  5  3