【问题标题】:How can I connect a dataset with the average of the values between two dates of another dataset in R?如何将数据集与 R 中另一个数据集的两个日期之间的平均值连接起来?
【发布时间】:2018-04-29 00:38:09
【问题描述】:

我想通过添加一个名为Average 的新列将两个数据集相互连接。此列是DateDate - diff 之间的平均持续时间。我有两个数据集,第一个叫做data,看起来像这样:

       Date   Weight   diff   Loc.nr  
2013-01-24     1040       7        2
2013-01-31     1000       7        2
2013-01-19      500       4        9
2013-01-23     1040       4        9
2013-01-28      415       5        9
2013-01-31      650       3        9

另一个叫Rain.duration,在Duration列中是当天下雨的小时数。该数据集如下所示:

      Date  Duration
2013-01-14       4.5
2013-01-15       0.0
2013-01-16       6.9
2013-01-17       0.0
2013-01-18       1.8
2013-01-19       2.1
2013-01-20       0.0
2013-01-21       0.0
2013-01-22       4.3
2013-01-23       0.0
2013-01-24       7.5
2013-01-25       4.7
2013-01-26       0.0
2013-01-27       0.7
2013-01-28       5.0
2013-01-29       0.0
2013-01-30       3.1
2013-01-31       2.8

我为此编写了一个代码:

for(i in 1:nrow(data)) {
  for(j in 1:nrow(Rain.duration)) {
    if(data$Date[i] == Rain.duration$Date[j]) {
      average <- as.array(Rain.duration$Duration[(j-(data$diff[i])):j])

      j <- nrow(Rain.duration)
    }
  }
  data$Average[i] <- mean(average)
}

这段代码的问题在于,由于我的数据集的大小,运行大约需要 3 天。有没有更快的方法来做到这一点?

我的预期结果是:

       Date   Weight   diff   Loc.nr   Average
2013-01-24     1040       7        2      1.96
2013-01-31     1000       7        2      2.98
2013-01-19      500       4        9      2.16
2013-01-23     1040       4        9      1.28
2013-01-28      415       5        9      2.98
2013-01-31      650       3        9      2.73

【问题讨论】:

  • 也许我误读了您的代码,但您是否试图获取每个日期的平均持续时间?您在预期输出中的平均值不是每个日期的平均持续时间,但也许这只是填充数据?
  • 我想要来自dataDateDate - diff 之间间隔的平均值。
  • 我不明白Weather 是如何在这里发挥作用的。 Duration 列与您要计算的内容有什么关系?
  • 我刚刚编辑了问题,但duration 是当天下雨的小时数。所以我想计算data$Datedata$Date - data$diff之间的平均下雨小时数。
  • 这听起来类似于my question,任何答案有帮助吗?

标签: r date merge dataset


【解决方案1】:

这是一个 dplyr 解决方案:

library(dplyr)

# add row number as a new column just to make it easier to read
weather_with_rows  <- Weather %>%
    mutate(Rownum = row_number())

# write function to filter by row number, then return the average duration
getavgduration  <- function(mydate, mydiff) {

    myrow = weather_with_rows %>%
         filter(Date == mydate) %>%
         pluck("Rownum")

    mystartrow = myrow -mydiff

    myduration = weather_with_rows %>%
        filter(
              Rownum <= myrow
            , Rownum >= mystartrow
        )

    mean(myduration$Duration)

}

# get the average duration for each Date/diff pair
averages  <- data %>%
    group_by(Date, Diff) %>%
    summarize(Average = getavgduration(Date, Diff)) %>%
    ungroup()


# join this back into the original data frame
#    this step might not be necessary 
#    and might be a big drag on performance, 
#    depending on the size of your real data
data_with_avg_duration  <- data %>%
    left_join(averages, by = c('Date','Diff')

【讨论】:

  • 感谢您的解决方案。如果我运行此代码,我会在以下位置收到错误消息:averages &lt;- data %&gt;% group_by(Date, diff) %&gt;% summarize(Average = getavgduration(Date, diff)) %&gt;% ungroup() 错误提示:Error in summarise_impl(.data, dots) : subscript out of bounds 你知道如何解决这个问题吗?
  • 我可能在getavgduration() 函数中弄错了关于大写(或天气df 中的持续时间列)的列名。看起来我在两个数据框中都大写了“日期”,而没有大写“持续时间”。该错误意味着找不到命名列,并且由于 R 区分大小写,我可能会遗漏一些东西。
  • 我编辑了我的答案,使所有列名都大写,在两个数据帧中保持一致。
【解决方案2】:

这个老问题还没有一个公认的答案,所以我觉得有义务发布一个替代解决方案,聚合在非等值连接中

OP 已请求根据data 中给出的每个日期间隔的每日降雨小时数的表Rain.duration 计算平均降雨持续时间。

library(data.table)
# make sure Date columns are of class Date
setDT(data)[, Date := as.Date(Date)]
setDT(Rain.duration)[, Date := as.Date(Date)]
# aggregate in a non-equi join and assign the result to a new column
data[,  Average := Rain.duration[data[, .(upper = Date, lower = Date - diff)], 
            on = .(Date <= upper, Date >= lower), 
            mean(Duration), by  = .EACHI]$V1][]
         Date Weight diff Loc.nr  Average
1: 2013-01-24   1040    7      2 1.962500
2: 2013-01-31   1000    7      2 2.975000
3: 2013-01-19    500    4      9 2.160000
4: 2013-01-23   1040    4      9 1.280000
5: 2013-01-28    415    5      9 2.983333
6: 2013-01-31    650    3      9 2.725000

关键部分是

Rain.duration[data[, .(upper = Date, lower = Date - diff)], 
              on = .(Date <= upper, Date >= lower), 
              mean(Duration), by  = .EACHI]
         Date       Date       V1
1: 2013-01-24 2013-01-17 1.962500
2: 2013-01-31 2013-01-24 2.975000
3: 2013-01-19 2013-01-15 2.160000
4: 2013-01-23 2013-01-19 1.280000
5: 2013-01-28 2013-01-23 2.983333
6: 2013-01-28 2013-01-23 2.983333
7: 2013-01-31 2013-01-28 2.725000

它使用源自data 的日期范围进行非等值连接

data[, .(upper = Date, lower = Date - diff)]
        upper      lower
1: 2013-01-24 2013-01-17
2: 2013-01-31 2013-01-24
3: 2013-01-19 2013-01-15
4: 2013-01-23 2013-01-19
5: 2013-01-28 2013-01-23
6: 2013-01-28 2013-01-23
7: 2013-01-31 2013-01-28

by = .EACHI 请求为每个日期间隔即时计算聚合 mean(Duration),从而避免创建和复制临时子集。

请注意,即使Rain.duration 有间隙或无序,此解决方案也会给出正确答案,因为它仅依赖于Date,而不是使用行号的其他解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 2016-09-13
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    相关资源
    最近更新 更多