0

我想data.table根据 a Condition、类别 ( Cat) 和Date.

仅当 时,才可能有资格重新计算行Condition==TRUE。在所有带有 的行中,只应选择各自Condition==TRUE最高的行。DateCat

一个简化的例子:

     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's 和's:DateResult

    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应该是Data1+Data2.

编辑:
受eddi回答的启发,我想出了另外两个可能的解决方案:

使用方法.I

    DT[DT[Condition==TRUE , .I[which.max(Date)], by=Cat][[2]], Result:=Data1+Data2]

使用方法.SD(参见 eddi 的注意事项):

    max_dates=DT[Condition==TRUE , .SD[which.max(Date)], by=Cat]
    setkey(DT, Cat, Date)
    DT[max_dates, Result:=Data1 + Data2]

关于速度/效率,有什么建议可以选择解决方案吗?

4

1 回答 1

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通过作为密钥一部分的列执行 a ),那么您必须擦除其密钥,或者使其具有与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
于 2013-05-21T19:40:15.567 回答