如何更新每个组中的单行?

时间:2013-09-30 23:30:56

标签: r data.table

我有足够大的数据,有史以来第一次需要data.table,而且我对它到目前为止的容易程度感到非常满意。我今天已经阅读了相当多的文档(当然不是全部),但我还没有找到它。

我有一个由placeidt2键入的数据表,另一列是t1。我想要做的是将t1设置为0t2最小的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"))

t2

由于ifelse位于密钥中,我想要更改的行是每个分组中的第一行。我能够使用i语句来使用它,但使用[.data.table的{​​{1}}参数有更好的方法吗?

我希望其中一个能起作用,但是在思考的时候,他们不会这样做:

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

我找到了什么工作(结果是所需的输出):

dt[, t1 := ifelse(t2 == min(t2), 0, t1), by = placeid]  # works

1 个答案:

答案 0 :(得分:7)

因为您知道dtplaceidt2进行了键控(即排序),所以placeid的第一行是您要更新的行。< / p>

只有在加入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)]按{{1}标识这些行}}

placeid

请注意,这将比上面的二进制搜索选项慢。