How to update one row in each group?

I have data that is large enough to need in the first place data.table, and I was very pleased with how much it has been so far. Today I read quite a lot of documentation (of course, almost not all), but I have not found this yet.

I have a data table with the keys placeidand t2one other column t1. What I would like to do is set t1to 0in each row, where t2at a minimum level, on placeid.

## Sample data
set.seed(47)
require(data.table)
dt <- data.table(placeid = rep(letters[1:3], each = 3), t1 = runif(9), t2 = runif(9))
setkeyv(dt, cols=c("placeid", "t2"))

Since it t2is in the key, the line I want to change is the first in each group. I managed to get it to work with the operator ifelse, but is there a better way to do this using an argument i [.data.table?

I was hoping that one of them would work, although, thinking a little more, it makes sense that they do not:

dt[1, t1 := 0, by = placeid] ## changes only first row
dt[which.min(t2), t1 := 0, by = placeid] ## changes only global min row

What I found to work (the result is the desired result):

dt[, t1 := ifelse(t2 == min(t2), 0, t1), by = placeid]  # works
+4
source share
1 answer

Since you know what dtis entered by the key (i.e. sorted) using placeidand t2, the first line placeidis the line you want to update.

mult = 'first' placeid

dt[unique(placeid),t1 := 0,mult='first']
dt
#    placeid        t1         t2
# 1:       a 0.0000000 0.13879758
# 2:       a 0.7615020 0.70198720
# 3:       a 0.9769620 0.92489205
# 4:       b 0.0000000 0.16219364
# 5:       b 0.6914124 0.50603611
# 6:       b 0.5735444 0.59930702
# 7:       c 0.0000000 0.03094497
# 8:       c 0.4689460 0.40050280
# 9:       c 0.3890619 0.90197352

, , , t2 == min (t2), .I[t2==min(t2)] placeid

dt[dt[,.I[t2 == min(t2)],by='placeid']$V1, t1 := 0]

, , .

+7

All Articles