将计数器添加到R中分类变量的连续观察值?

将计数器添加到R中分类变量的连续观察值?,r,dataframe,for-loop,data-cleaning,R,Dataframe,For Loop,Data Cleaning,我有一个数据框架,其中一个变量将我的观察结果(ID)分组,另一个变量是分类的(类型)。我在R中工作,试图创建一个新变量,用于统计ID中相同类型的连续观测值(数据为时间序列)。请参见下表示例-计数器是我要创建的变量。0是否被计数并不重要 dat <- data.frame(id = c(rep("a", 7), rep("b", 4)), type = c(0, 1, 1, 2, 2, 0, 1, 1, 1, 2, 0),

我有一个数据框架,其中一个变量将我的观察结果(ID)分组,另一个变量是分类的(类型)。我在R中工作,试图创建一个新变量,用于统计ID中相同类型的连续观测值(数据为时间序列)。请参见下表示例-计数器是我要创建的变量。0是否被计数并不重要

dat <- data.frame(id = c(rep("a", 7), rep("b", 4)),
                  type = c(0, 1, 1, 2, 2, 0, 1, 1, 1, 2, 0),
                  counter = c(0, 1, 2, 1, 2, 0, 1, 1, 2, 1, 0))
dat
结果:

   id type counter
1   a    0       0
2   a    1       1
3   a    1       2
4   a    2       1
5   a    2       2
6   a    0       0
7   a    1       1
8   b    1       1
9   b    1       2
10  b    2       1
11  b    0       0
注意:一些代码在
case_when()
参数中重复,但这些重复是覆盖许多条件所必需的

我在各种条件下测试了这段代码,它看起来很健壮。它没有处理的一件事是,如果在最后一个值处有一个repeat(它将返回
NA
,因为我使用
lag()

这段较长的代码也涵盖了这种情况,并且(我认为)无论您的代码是什么,都应该可以工作:

dat %>%
  mutate(counter = case_when(
    type == 0 ~ 0,
    type != lag(type) ~ 1
  )) %>%
  mutate(counter = case_when(
    id != lag(id) ~ 1,
    type == lag(type) ~ lag(counter) + 1,
    T ~ counter
  )) %>%
  mutate(counter = case_when(
    is.na(counter) ~ lag(counter) + 1,
    T ~ counter
  ))

对于每个
id
type
和以
type
0开头的连续行,使用
ave
seq\u沿
创建一个序列。未使用任何软件包:

transform(dat, 
  counter = (type > 0) * ave(type, id, type, cumsum(type == 0), FUN = seq_along))
给予:

   id type counter
1   a    0       0
2   a    1       1
3   a    1       2
4   a    2       1
5   a    2       2
6   a    0       0
7   a    1       1
8   b    1       1
9   b    1       2
10  b    2       1
11  b    0       0

您在for循环中忘记了一个
(i in 1:nrow(dat)
--added–我不理解您的问题。您没有什么开始(没有
计数器
?)您想创建什么
计数器
是您第一个
dat
指令中的计数器,还是您下面的代码给出的计数器?@vaettchen谢谢。我需要在我的帖子中提供的
dat
中创建
计数器
变量。用我的代码创建的
计数器
不正确。谢谢-这个解决方案工作得很好ly。非常简单。接近一百万次观察,所以这是非常快的。我用ave尝试了几个解决方案,但始终无法找到它-这有助于看到这一点。标记为已回答。谢谢!对帖子进行了投票。这确实很有帮助,但我接受了另一个答案,因为它简单,不含Na,而且很健壮。
transform(dat, 
  counter = (type > 0) * ave(type, id, type, cumsum(type == 0), FUN = seq_along))
   id type counter
1   a    0       0
2   a    1       1
3   a    1       2
4   a    2       1
5   a    2       2
6   a    0       0
7   a    1       1
8   b    1       1
9   b    1       2
10  b    2       1
11  b    0       0