我想仅针对某些行重新计算data.table
中的列,具体取决于Condition
,类别(Cat
)和Date
。
只有在Condition==TRUE
时才有资格重新计算一行。在Condition==TRUE
的所有行中,只应选择相应Date
的{{1}}行最高的行。
简化示例:
Cat
我发现了如何提取行的 DF = data.frame(Cat=rep(c("A","B","C"),each=3), Date=rep(c("01-08-2013","01-07-2013","01-04-2013"),3),
Condition=c(TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE),
Data1=c(1:9), Data2=rep(c(1:3),3), Result=c(1:1))
DF$Date = as.Date(DF$Date , "%m-%d-%Y")
DT = data.table(DF)
DT
Cat Date Condition Data1 Data2 Result
1: A 2013-01-08 TRUE 1 1 1
2: A 2013-01-07 TRUE 2 2 1
3: A 2013-01-04 FALSE 3 3 1
4: B 2013-01-08 FALSE 4 1 1
5: B 2013-01-07 FALSE 5 2 1
6: B 2013-01-04 FALSE 6 3 1
7: C 2013-01-08 FALSE 7 1 1
8: C 2013-01-07 FALSE 8 2 1
9: C 2013-01-04 TRUE 9 3 1
和Cat
,其中Date
必须重新计算:
Result
但是,我不知道如何计算这些行的新 setkey(DT, Condition, Cat, Date)
DT[J(TRUE), max(Date), by=Cat]
Cat V1
1: A 2013-01-08
2: C 2013-01-04
。
在此简化示例中,新Result
应为Result
。
修改
受到eddi回答的启发,我想出了两个可能的解决方案:
使用Data1+Data2
的方法:
.I
使用 DT[DT[Condition==TRUE , .I[which.max(Date)], by=Cat][[2]], Result:=Data1+Data2]
的方法(参见eddi的注意事项):
.SD
对于速度/效率,是否有任何建议可供选择?
答案 0 :(得分:1)
这样的事情会起作用:
dt = data.table(DF)
max_dates = dt[Condition == TRUE,
list(Date = max(Date), Condition = TRUE),
by = Cat]
setkey(dt, Cat, Date, Condition)
dt[max_dates, Result := Data1 + Data2]
dt
# Cat Date Condition Data1 Data2 Result
#1: A 2013-01-04 FALSE 3 3 1
#2: A 2013-01-07 TRUE 2 2 1
#3: A 2013-01-08 TRUE 1 1 2
#4: B 2013-01-04 FALSE 6 3 1
#5: B 2013-01-07 FALSE 5 2 1
#6: B 2013-01-08 FALSE 4 1 1
#7: C 2013-01-04 TRUE 9 3 12
#8: C 2013-01-07 FALSE 8 2 1
#9: C 2013-01-08 FALSE 7 1 1
警告提示:以上内容依赖于max_dates
没有密钥 - 如果您将其更改为拥有密钥(例如,如果您执行了by
如果是键的一部分,那么你必须要删除它的键,或者让它在代码中使用与dt
相同的键才能使合并正常工作。
这是另一种方法:
dt = data.table(DF)
dt[, Result := Result + (Data1 + Data2 - Result) * Condition * (Date == max(Date)),
by = list(Cat, Condition)]
# I could've used ifelse here instead, but ifelse is slow