Question: I would like to update the value in a table with values of the previous row, within groups, (and probably stop the updates on a given condition)

Here is an example:

```
set.seed(12345)

field <- data.table(time=1:3, player = letters[1:2], prospects = round(rnorm(6),2))
setkey(field, player, time)
field[time == 1, energy := round(rnorm(2),2)] #initial level - this is what I want to propagate down the table
#let 'prospects < 0.27' be the condition that stops the process, and sets 'energy = 0'
#player defines the groups within which the updates are made

```

Here is the table I have. 

```
> field
time player prospects energy
1:    1      a      0.81  -0.32
2:    2      a      0.25     NA
3:    3      a      2.05     NA
4:    1      b      1.63  -1.66
5:    2      b      2.20     NA
6:    3      b      0.49     NA

```

Here is the table I want.

```
> field
time player prospects energy
1:    1      a      0.81  -0.32
2:    2      a      0.25  0
3:    3      a      2.05  0
4:    1      b      1.63  -1.66
5:    2      b      2.20  -1.66
6:    3      b      0.49  -1.66

```

Thanks in advance

Answer: 
Probably there are better ways, but this is what came to my mind. This makes use of `roll=TRUE` argument. The idea is to first set `energy=0.0` where `prospects < 0.27`:

```
field[prospects < 0.27, energy := 0.0]

```

Then, if we remove the NA values from `field`, we can use `roll=TRUE` by doing a join with all combinations as follows:

```
field[!is.na(energy)][CJ(c("a", "b"), 1:3), roll=TRUE][, prospects := field$prospects][]
#    player time prospects energy
# 1:      a    1      0.81   0.63
# 2:      a    2      0.25   0.00
# 3:      a    3      2.05   0.00
# 4:      b    1      1.63  -0.28
# 5:      b    2      2.20  -0.28
# 6:      b    3      0.49  -0.28

```

We've to reset `prospects` because the `roll` changes it too. You could do it better, but you get the idea.

---

A variation, so that the roll is performed only on `energy` column:

```
field[!is.na(energy)][CJ(c("a", "b"), 1:3), list(energy), 
           roll=TRUE][, prospects := field$prospects][]

```

---

Or it may be simpler to use `na.locf` from package `zoo` :

```
field[time == 1, energy := round(rnorm(2),2)]
field[prospects < 0.27, energy := 0.0]
require(zoo)
field[, energy := na.locf(energy, na.rm=FALSE)]

```

which works if the first row of each group is guaranteed to be non-NA, which it is here by construction. But if not, you can run na.locf by group, too :

```
field[, energy := na.locf(energy, na.rm=FALSE), by=player]

```
something like this ?

```
ddply(field, 'player', function(x) {
  baseline <- x[x$time == 1, 'energy']
  x$energy <- baseline
  ind <- which(x$prospects < 0.27)
  if (length(ind)) {
    x[min(ind):nrow(x), 'energy'] <- 0
  }
  x
})

```