如何使用R中data.table中组内的最后一行进行一些计算?

nsD*_*Sci 3 r data.table

我有这个data.table:

样品:

id cond date
1  A1   2012-11-19
1  A1   2013-05-09
1  A2   2014-09-05
2  B1   2015-03-05
2  B1   2015-07-06
3  A1   2015-02-05
4  B1   2012-09-26
4  B1   2015-02-05
5  B1   2012-09-26
Run Code Online (Sandbox Code Playgroud)

我想从今天的'id'和'cond'组中计算从今天开始的过期天数,所以我试图得到每组中最后一个日期和sys.date之间的天数差异.期望的输出是;

id cond date        overdue
1  A1   2012-11-19  NA
1  A1   2013-05-09  832 
1  A2   2014-09-05  348
2  B1   2015-03-05  NA 
2  B1   2015-07-06  44
3  A1   2015-02-05  195
4  B1   2012-09-26  NA 
4  B1   2015-02-05  195
5  B1   2012-09-26  1057
Run Code Online (Sandbox Code Playgroud)

我尝试通过以下代码实现此目的:

sample <- sample[ , overdue := Sys.Date() - date[.N], by = c('id','cond')]
Run Code Online (Sandbox Code Playgroud)

但是我得到了以下输出,其值是回收:

id cond date        overdue
1  A1   2012-11-19  832
1  A1   2013-05-09  832 
1  A2   2014-09-05  348
2  B1   2015-03-05  44 
2  B1   2015-07-06  44
3  A1   2015-02-05  195
4  B1   2012-09-26  195 
4  B1   2015-02-05  195
5  B1   2012-09-26  1057
Run Code Online (Sandbox Code Playgroud)

我不确定,如何限制我的代码只是为最后一行做计算而不是回收.我相信会有办法做到这一点,感谢帮助.

Fra*_*ank 6

您可以创建一个过期值及其所属行的表:

bycols    = c("id","cond")
newcolDT2 = DT[, Sys.Date() - date[.N], by = bycols]

DT[newcolDT2, overdue := V1, on = bycols, mult = "last"]
#    id cond       date   overdue
# 1:  1   A1 2012-11-19   NA days
# 2:  1   A1 2013-05-09  832 days
# 3:  1   A2 2014-09-05  348 days
# 4:  2   B1 2015-03-05   NA days
# 5:  2   B1 2015-07-06   44 days
# 6:  3   A1 2015-02-05  195 days
# 7:  4   B1 2012-09-26   NA days
# 8:  4   B1 2015-02-05  195 days
# 9:  5   B1 2012-09-26 1057 days
Run Code Online (Sandbox Code Playgroud)

这是(可以说是丑陋的)单行版本:

DT[J(unique(DT[, bycols, with=FALSE])), 
  overdue := Sys.Date() - date, on = bycols, mult = "last"]
Run Code Online (Sandbox Code Playgroud)

数据:

DT <- data.table(read.table(header=TRUE,text="id cond date
1  A1   2012-11-19
1  A1   2013-05-09
1  A2   2014-09-05
2  B1   2015-03-05
2  B1   2015-07-06
3  A1   2015-02-05
4  B1   2012-09-26
4  B1   2015-02-05
5  B1   2012-09-26"))[, date := as.IDate(date)]

# anyone know how to do this with fread()?
Run Code Online (Sandbox Code Playgroud)