R - 条件递增

时间:2014-11-26 18:08:15

标签: r dataframe apply

这对代码来说应该是微不足道的,但却无法想到R中优雅的单行代码。我有一个如下数据框:

data <- data.frame( index= seq(1:20), event=rep(0,20)   )
data$event[10] <- 1
data$event[15] <- 1

我只想添加在{10}中递增的startstop个计数器列,并在观察到event=1后立即重置。因此,这两个附加列的所需输出将是:

  index event start stop
1   1    0     0    10
2   2    0    10    20
3   3    0    20    30
4   4    0    30    40
5   5    0    40    50
6   6    0    50    60
7   7    0    60    70
8   8    0    70    80
9   9    0    80    90
10  10   1    90    100
11  11   0    0     10
12  12   0    10    20
13  13   0    20    30
14  14   0    30    40
15  15   1    40    50
16  16   0    0     10
17  17   0    10    20
18  18   0    20    30
19  19   0    30    40
20  20   0    40    50

显然,data$stop <- data$start + 10但我如何apply() start增加loigc如上所述?

3 个答案:

答案 0 :(得分:7)

这个怎么样:

Reduce(function(x,y) (1-y)*(x+10), data$event[-nrow(data)], accumulate=T, init=0)

答案 1 :(得分:4)

您可以使用

获取您的值
data$start <- 10*(ave(
    rep(0,nrow(data)), 
    cumsum(c(0, head(data$event,-1))), 
    FUN=seq_along)-1
)
data$end <- data$start + 10

这里我们使用cumsum来跟踪事件发生的时间(但我们需要将它们移动一步,以便在事件之后而不是在事件处发生重置)。我们在组内使用ave来生成每个组的序列。

答案 2 :(得分:2)

所以遗憾的是,当该循环的迭代不依赖于先前的迭代时,apply系列函数仅替换for循环。

你可以写一个for循环,如:

data <- data.frame( index= seq(1:20), event=rep(0,20)   )
data$event[10] <- 1
data$event[15] <- 1
print(data)
data$start = rep(0, 20)
for(i in 2:20){
  if(data$event[i] == 1){
    data$start[i] = 0
  } else  data$start[i] = data$start[i-1] + 10
}
data$stop = data$start+10
print(data)