R:每次新序列开始时,如何开始一个新的sub_id



假设我有如下数据:

tibble(
A = c(1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5),
B = c(1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 1, 2, 3, 4, 1, 1),
)

# A tibble: 16 x 2
A     B
<dbl> <dbl>
1     1     1
2     2     1
3     2     2
4     2     1
5     2     2
6     2     3
7     3     1
8     3     2
9     3     1
10     3     1
11     4     1
12     4     2
13     4     3
14     4     4
15     4     1
16     5     1

每次在变量a(即(定义的组内开始新序列时,我如何创建sub_id

tibble(
A = c(1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5),
B = c(1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 1, 2, 3, 4, 1, 1),
sub_id = c(1, 1, 1, 2, 2, 2, 1, 1, 2, 3, 1, 1, 1, 1, 2, 1)
)
# A tibble: 16 x 3
A     B sub_id
<dbl> <dbl>  <dbl>
1     1     1      1
2     2     1      1
3     2     2      1
4     2     1      2
5     2     2      2
6     2     3      2
7     3     1      1
8     3     2      1
9     3     1      2
10     3     1      3
11     4     1      1
12     4     2      1
13     4     3      1
14     4     4      1
15     4     1      2
16     5     1      1

希望这是明确的。我想我在追求一种与行号相反的方法

提前感谢

詹姆斯。

使用base R

df$sub_id <- with(df, ave(B ==1, A, FUN = cumsum))

您得到了"配料";已经布局。

(i( 对于A列的每组(ii(检查新序列是否启动

以下内容基于{dplyr}。为了演示的目的,我创建了一个额外的列/变量来显示";启动条件";。您可以将其合并为一个调用。

我使用了这样一个事实,即在TRUE/FALSE上求和将TRUE编码为1。如果这对你来说不明显,你可以使用as.numeric(B == 1)

library(dplyr)
library(tibble)
# load example data
df <- tibble(
A = c(1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5),
B = c(1, 1, 2, 1, 2, 3, 1, 2, 1, 1, 1, 2, 3, 4, 1, 1),
sub_id = c(1, 1, 1, 2, 2, 2, 1, 1, 2, 3, 1, 1, 1, 1, 2, 1)
)
# perform group-wise operations 
df %>% 
group_by(A) %>% 
mutate(
# --------------- highlight start of new sequence --------------
start = B == 1
# --------------- create cumsum over TRUEs----------------------
, sub_id2 = cumsum(start)
)

这就产生了你想要的:

# A tibble: 16 x 5
# Groups:   A [5]
A     B sub_id start sub_id2
<dbl> <dbl>  <dbl> <lgl>   <int>
1     1     1      1 TRUE        1
2     2     1      1 TRUE        1
3     2     2      1 FALSE       1
4     2     1      2 TRUE        2
5     2     2      2 FALSE       2
6     2     3      2 FALSE       2
7     3     1      1 TRUE        1
8     3     2      1 FALSE       1
9     3     1      2 TRUE        2
10     3     1      3 TRUE        3
11     4     1      1 TRUE        1
12     4     2      1 FALSE       1
13     4     3      1 FALSE       1
14     4     4      1 FALSE       1
15     4     1      2 TRUE        2
16     5     1      1 TRUE        1

我们可以使用group_bycumsum:

library(dplyr)
df %>%
group_by(A) %>%
mutate(sub_id = cumsum(B==1)

输出:

# Groups:   A [5]
A     B sub_id
<dbl> <dbl>  <int>
1     1     1      1
2     2     1      1
3     2     2      1
4     2     1      2
5     2     2      2
6     2     3      2
7     3     1      1
8     3     2      1
9     3     1      2
10     3     1      3
11     4     1      1
12     4     2      1
13     4     3      1
14     4     4      1
15     4     1      2
16     5     1      1

data.table选项

> setDT(df)[, sub_id := cumsum(B == 1), A][]
A B sub_id
1: 1 1      1
2: 2 1      1
3: 2 2      1
4: 2 1      2
5: 2 2      2
6: 2 3      2
7: 3 1      1
8: 3 2      1
9: 3 1      2
10: 3 1      3
11: 4 1      1
12: 4 2      1
13: 4 3      1
14: 4 4      1
15: 4 1      2
16: 5 1      1

最新更新