创建一定值的连续运行计数器

时间:2014-11-22 12:12:01

标签: r

我想在SOG列中创建一个连续运行零的计数器。

对于SOG中第一个0的序列,将列中的计数器设置为1.对于第二轮零,设置'停止'到2,等等。

SOG Stops
--- -----
4   0
4   0
0   1
0   1
0   1
3   0
4   0
5   0
0   2
0   2
1   0
2   0
0   3
0   3
0   3

4 个答案:

答案 0 :(得分:7)

SOG <- c(4,4,0,0,0,3,4,5,0,0,1,2,0,0,0)
#run length encoding:
tmp <- rle(SOG)
#turn values into logicals
tmp$values <- tmp$values == 0
#cumulative sum of TRUE values
tmp$values[tmp$values] <- cumsum(tmp$values[tmp$values])
#inverse the run length encoding
inverse.rle(tmp)
#[1] 0 0 1 1 1 0 0 0 2 2 0 0 3 3 3

答案 1 :(得分:3)

尝试

 df$stops<- with(df, cumsum(c(0, diff(!SOG))>0)*!SOG)
 df$stops
 # [1] 0 0 1 1 1 0 0 0 2 2 0 0 3 3 3

答案 2 :(得分:2)

使用dplyr

 library(dplyr)
 df <- df %>% mutate(Stops = ifelse(SOG == 0, yes = cumsum(c(0, diff(!SOG) > 0)), no = 0))
 df$Stops
 #[1] 0 1 1 1 0 0 0 2 2 0 0 3 3 3
编辑:除了我们这些仍然是初学者的人之外,这个问题的许多答案都使用了逻辑(即TRUE,FALSE)。在!之类的数字变量之前SOG测试值是0,如果是,则分配TRUE,否则分配FALSE

SOG
#[1] 4 0 0 0 3 4 5 0 0 1 2 0 0 0
!SOG
#[1] FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE
#[12]  TRUE  TRUE  TRUE

diff()取值和前面的值之间的差值。请注意,此列表中的元素少于SOG中的元素,因为第一个元素没有用于计算差异的滞后。在逻辑方面,diff(!SOG)会为1TRUE - FALSE = 1FALSE - TRUE = -1生成0

diff(SOG)
#[1] -4  0  0  3  1  1 -5  0  1  1 -2  0  0
diff(!SOG)
#[1]  1  0  0 -1  0  0  1  0 -1  0  1  0  0

所以cumsum(diff(!SOG) > 0)只关注TRUE - FALSE更改

cumsum(diff(!SOG) > 0)
#[1] 1 1 1 1 1 1 2 2 2 2 3 3 3

但由于差异列表是一个较短的元素,我们可以附加一个元素:

cumsum(c(0, diff(!SOG) > 0))  #Or cumsum( c(0, diff(!SOG)) > 0 ) 
#[1] 0 1 1 1 1 1 1 2 2 2 2 3 3 3

然后将!SOG的列表“乘以”@akrun的答案,或使用ifelse()命令。如果是SOG == 0的特定元素,我们会使用cumsum(c(0, diff(!SOG) > 0))中的相应元素;如果不是0,我们会指定0

答案 3 :(得分:1)

带有 rle 的单行是 -

df <- data.frame(SOG = c(4,4,0,0,0,3,4,5,0,0,1,2,0,0,0))
df <- transform(df, Stops = with(rle(SOG == 0), rep(cumsum(values) * values, lengths)))
df

#   SOG Stops
#1    4     0
#2    4     0
#3    0     1
#4    0     1
#5    0     1
#6    3     0
#7    4     0
#8    5     0
#9    0     2
#10   0     2
#11   1     0
#12   2     0
#13   0     3
#14   0     3
#15   0     3