3

我有数据,其中连续的零运行被非零值的运行分隔。我想为“SOG”列中的零运行创建一个计数器。

对于 SOG 中的第一个 0 序列,将 Stops 列中的计数器设置为 1。对于第二次运行的零,将“Stops”设置为 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

4 回答 4

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
于 2014-11-22T12:19:25.373 回答
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
于 2014-11-22T12:21:18.647 回答
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赋值,否则。TRUEFALSE

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()取值与之前的值之间的差。请注意,此列表中的元素比 in 少一个,SOG因为第一个元素没有用于计算差异的滞后。当涉及到逻辑时,diff(!SOG)产生1for TRUE - FALSE = 1FALSE - TRUE = -10其他。

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

然后将该列表“乘以” !SOGas in@akrun的答案或使用该ifelse()命令。如果是 的特定元素SOG == 0,我们使用来自 的对应元素cumsum(c(0, diff(!SOG) > 0));如果不是0,我们分配0.

于 2014-11-22T13:18:56.203 回答
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
于 2021-08-02T05:00:04.270 回答