【问题标题】:calculate elapsed days from non-sequential table从非顺序表计算经过的天数
【发布时间】:2016-03-16 16:04:46
【问题描述】:

我有一张加油表,a,像这样:

a = setDT(structure(list(date = structure(c(NA, 16837, 16843, 16847, 16852, 
16854, 16858, 16862, 16867, 16871, 16874), class = "Date"), km = c(NA, 
NA, 421, 351, 286, 350, 414, 332, 401, 321, 350)), .Names = c("date", 
"km"), class = c("data.table", "data.frame"), row.names = c(NA, 
-11L)), key = "date")

它有加油的日期和加油后行驶的公里数。我还得到了一张不同的表格,上面有轮胎压力调整和换油的日期,actions,像这样:

actions = setDT(structure(list(date = structure(c(16841, 16843, 16858, 16869), class = "Date"), 
    action = structure(c(1L, 2L, 2L, 2L), .Label = c("oil", "tires"
    ), class = "factor")), .Names = c("date", "action"), row.names = c(NA, 
-4L), class = c("data.table", "data.frame")), key = "action")

我需要将油耗(在a 的真实版本中我也有加仑)与自上次轮胎压力检查和自上次换油以来经过的天数联系起来。必须有一种简单的方法来实现这一点,但经过几个小时的尝试,我被卡住了。

这是我尝试过的:

library(data.table)
library(lubridate)
library(reshape2)

b <- dcast(actions, date ~ action, value.var = "date")

d <- seq(min(a$date, b$date, na.rm = TRUE), max(a$date, b$date, na.rm = TRUE), by = "day")
d <- data.table(date=d)
d <- b[d,]
d$daysOil <- as.double(difftime(d$date, d$date[! is.na(d$oil)], units = "days"))
d$daysOil[which(d$daysOil < 0)] <- NA

如果我尝试计算自上次“轮胎”事件(更接近之前加油日期的事件)以来经过的天数,事情会变得更加复杂,这就是我'我卡住了。

我的预期输出是:

expected
         date  km daysoil daysTires
1        <NA>  NA      NA        NA
2  2016-02-06  NA      NA        NA
3  2016-02-12 421       2         0
4  2016-02-16 351       6         4
5  2016-02-21 286      11         9
6  2016-02-23 350      13        11
7  2016-02-27 414      17         0
8  2016-03-02 332      21         4
9  2016-03-07 401      26         9
10 2016-03-11 321      30         2
11 2016-03-14 350      33         5

我会很感激任何解决方案,但最好使用 data.tabledplyr 包。

########## 编辑##########

如果您能想到更好的信息(表格)结构来促进这项任务,我们也将不胜感激!

【问题讨论】:

    标签: r data.table lubridate


    【解决方案1】:

    这是一种选择:

    actions[, date.copy := date]
    
    cbind(a,
          dcast(actions[, .SD[a, .(days = date - date.copy, N = .I), roll = T, on = 'date']
                        , by = action],
                N ~ action, value.var = 'days'))
    #          date  km  N     oil   tires
    # 1:       <NA>  NA  1 NA days NA days
    # 2: 2016-02-06  NA  2 NA days NA days
    # 3: 2016-02-12 421  3  2 days  0 days
    # 4: 2016-02-16 351  4  6 days  4 days
    # 5: 2016-02-21 286  5 11 days  9 days
    # 6: 2016-02-23 350  6 13 days 11 days
    # 7: 2016-02-27 414  7 17 days  0 days
    # 8: 2016-03-02 332  8 21 days  4 days
    # 9: 2016-03-07 401  9 26 days  9 days
    #10: 2016-03-11 321 10 30 days  2 days
    #11: 2016-03-14 350 11 33 days  5 days
    

    上面发生了几件简单的事情 - 分块运行以了解。

    【讨论】:

    • 惊人的一个班轮。我会花几年的时间来想出这样的东西,谢谢!似乎data.table(和一般的 R)对我来说总是有一颗隐藏的宝石。这次是roll = TRUE
    猜你喜欢
    • 1970-01-01
    • 2020-01-12
    • 2021-03-14
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多