从R中的零开始按顺序添加值

时间:2016-08-19 22:32:51

标签: r sum sequence

嗨我试图在向量中添加值,因为R中的值为零。 我有这样的矢量:

wdnew
 [1] 1 0 0 1 1 0 0 1 1 1 1 1

我想创建一个新的向量来计算自零值以来的迭代次数或位数。如果我做得恰到好处,我会得到一个这样的矢量:

wdseq
 [1] 1 0 0 1 2 0 0 1 2 3 4 5

这应该是直截了当但我无法弄清楚如何生成序列,任何建议? 谢谢,

6 个答案:

答案 0 :(得分:5)

一种选择是使用rleid创建群组变量并按群组cumsum执行:

wdnew <- c(1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1)
ave(wdnew, data.table::rleid(wdnew != 0), FUN=cumsum)
# [1] 1 0 0 1 2 0 0 1 2 3 4 5

答案 1 :(得分:4)

没有data.table的选项:

wdnew <- c(1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1)
rl <- rle(wdnew)
unlist(mapply(function(a,b) b * seq_len(a), rl$lengths, rl$values))
#  [1] 1 0 0 1 2 0 0 1 2 3 4 5

正如@DirtySockSniffer建议的那样,这可以组合成一行:

with(rle(wdnew), unlist(mapply(function(a,b) b * seq_len(a), lengths, values)))

或者踩下@ user20650的建议:

wdnew * sequence(rle(wdnew)$lengths)

我认为这最后一个可能会赢得代码高手...

(所有假设wdnew都是0和1。)

答案 2 :(得分:3)

如果你想使用一个循环&#39;因为你喜欢使用循环,你可以这样做:

nums = c(1,0,0,1,1,0,0,1,1,1,1,1)

runningCount = 0
for(i in 1:length(nums)){
   if(nums[i] == 1){ 
      runningCount = runningCount + 1
      nums[i] = runningCount
   } else {
      runningCount = 0
   }
}

nums
 [1] 1 0 0 1 2 0 0 1 2 3 4 5

答案 3 :(得分:3)

  

我试图在向量中添加值,因为零

也许

git log --oneline --decorate --all --graph

注意,我采用的是更一般的设置,其中k <- rle(as.logical(x))$lengths ave(x, rep.int(1:length(k), k), FUN = cumsum) 不仅仅是0/1二进制。但是x会给出as.logical(x)二进制结果,指示零(TRUE / FALSE)和非零(FALSE)的块。如果您的TRUE肯定是0/1二进制,只需使用

x

是合法的。

示例

k <- rle(x)$lengths
ave(x, rep.int(1:length(k), k), FUN = cumsum)

答案 4 :(得分:3)

我可能会因为这个问题获得最长的答案而获奖。

好吧,至少我没有调用任何软件包并坚持基本功能(FWIW)。

vec <-  c(1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1); res  <- vec

for(i in 2:length(vec)){m <- 1
  while(vec[i-m] > 0 & vec[i]>0){m <- m+1}
      res[i] <- m; if(vec[i]==0) res[i] <- 0}
  

[1] 1 0 0 1 2 0 0 1 2 3 4 5

答案 5 :(得分:1)

以下是diffave

的另一种方法
ave(wdnew, cumsum(c(TRUE, diff(wdnew == 1)!=0)), FUN = seq) * wdnew
#[1] 1 0 0 1 2 0 0 1 2 3 4 5

数据

wdnew <- c(1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1)