计算 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 的步骤
- 在
id
、len0
内,总结第一个值(如果您只想要那些从 1
开始的值,请参见下文)和 len
gth 运行
如果您只想知道那些序列从 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
(我想你现在只需要 id
和 len
。)
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
我有一个包含相应值的数据集,我想知道每个长度出现的次数。 更具体地说,我想找出有多少 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 的步骤 - 在
id
、len0
内,总结第一个值(如果您只想要那些从1
开始的值,请参见下文)和len
gth 运行
如果您只想知道那些序列从 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
(我想你现在只需要 id
和 len
。)
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