【问题标题】:Selecting elements from a dataframe从数据框中选择元素
【发布时间】:2019-09-20 07:00:24
【问题描述】:

我有一个非常大的电表数据集。它看起来像这样(每 5 分钟有一行):

df
                 Time Type    Energy
1 2019-08-31 23:55:00    a   -0.3558
2 2019-08-30 14:55:00    b   -3.1189
3 2019-08-29 15:15:00    c   27.3856
4 2019-08-28 19:20:00    b -155.7758
5 2019-08-27 18:30:00    a -149.3617

还有一个关税表,如下所示:

     tf
       Hour      0      1      2      3      4      5      6
    1     0 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495
    2     1 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495
    3     2 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495
    4     3 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495 0.1495
...............................

以此类推,最多 23 小时,以天为列标题。 我需要计算数据集中每 5 分钟间隔的能源成本。似乎可以使用:

require(lubridate)
xlt <- as.POSIXlt(df$Time)
cost <- tf[xlt$hour,xlt$wday]* df$Energy

但这不起作用,因为每个小时都选择了所有天,而需要的是按小时和天索引的关税表中的单个元素。结果如下:

cost
             4           3           2           1           0
23  -0.0531921  -0.0531921  -0.0531921  -0.0531921  -0.0531921
14  -0.7157876  -0.7157876  -0.7157876  -0.7157876  -0.7157876
15   6.2849952   6.2849952   6.2849952   6.2849952   6.2849952
19 -83.9631562 -83.9631562 -83.9631562 -83.9631562 -35.7505461
18 -80.5059563 -80.5059563 -80.5059563 -80.5059563 -34.2785102

    dput(cost)
        structure(list(`4` = c(-0.0531921, -0.71578755, 6.2849952, -83.9631562, 
        -80.5059563), `3` = c(-0.0531921, -0.71578755, 6.2849952, -83.9631562, 
        -80.5059563), `2` = c(-0.0531921, -0.71578755, 6.2849952, -83.9631562, 
        -80.5059563), `1` = c(-0.0531921, -0.71578755, 6.2849952, -83.9631562, 
        -80.5059563), `0` = c(-0.0531921, -0.71578755, 6.2849952, -35.7505461, 
        -34.27851015)), class = "data.frame", row.names = c(23L, 14L, 
        15L, 19L, 18L))

这是数据:

    dput(head(tf))
    structure(list(Hour = 0:5, `0` = c(0.1495, 0.1495, 0.1495, 0.1495, 
    0.1495, 0.1495), `1` = c(0.1495, 0.1495, 0.1495, 0.1495, 0.1495, 
    0.1495), `2` = c(0.1495, 0.1495, 0.1495, 0.1495, 0.1495, 0.1495
    ), `3` = c(0.1495, 0.1495, 0.1495, 0.1495, 0.1495, 0.1495), `4` = c(0.1495, 
    0.1495, 0.1495, 0.1495, 0.1495, 0.1495), `5` = c(0.1495, 0.1495, 
    0.1495, 0.1495, 0.1495, 0.1495), `6` = c(0.1495, 0.1495, 0.1495, 
    0.1495, 0.1495, 0.1495)), row.names = c(NA, 6L), class = "data.frame")
 dput(df)
structure(list(Time = structure(list(sec = c(0, 0, 0, 0, 0), 
    min = c(55L, 55L, 15L, 20L, 30L), hour = c(23L, 14L, 15L, 
    19L, 18L), mday = 31:27, mon = c(7L, 7L, 7L, 7L, 7L), year = c(119L, 
    119L, 119L, 119L, 119L), wday = 6:2, yday = 242:238, isdst = c(0L, 
    0L, 0L, 0L, 0L), zone = c("AEST", "AEST", "AEST", "AEST", 
    "AEST"), gmtoff = c(NA_integer_, NA_integer_, NA_integer_, 
    NA_integer_, NA_integer_)), class = c("POSIXlt", "POSIXt"
)), Type = structure(c(1L, 2L, 3L, 2L, 1L), .Label = c("a", "b", 
"c"), class = "factor"), Energy = c(-0.3558, -3.1189, 27.3856, 
-155.7758, -149.3617)), row.names = c(NA, -5L), class = "data.frame")

性能也是一个问题。如果这非常无知,我深表歉意,但我已经搜索了好几天,但没有找到类似的例子。

【问题讨论】:

  • 嗨@Ronald,你能用dput更新这个并添加预期的输出吗,见stackoverflow.com/questions/5963269/…
  • 所以你必须在tf 中每小时有一行,所以 24 行?列代表什么?您期望的最终输出是df 中的一个新列,其能源成本基于Time 列的小时计算为 5 分钟的持续时间?你能显示df 前 6 行的输出吗?
  • 是的,没错,罗纳克。列是一周中的几天,0-6。成本列在上面显示为一个单独的变量,但将作为一个额外的列添加到 df。它旨在完全按照您的描述包含 5 分钟期间的成本。需要天数的原因是关税因星期几和小时而异

标签: r datetime dplyr lubridate


【解决方案1】:

尝试使用具有行和列索引的cbind 创建一个矩阵,然后使用它从tf 中提取关税,然后乘以Energy

df$cost <- df$Energy * tf[cbind(df$Time$hour + 1,  df$Time$wday + 1)]

在行索引中添加 1,因为小时数从 0 开始,但行号从 1 开始,并在列索引中添加 1,因为我们要从第 2 列开始提取值(因为第 1 列是 Hour)。

【讨论】:

    猜你喜欢
    • 2017-06-08
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多