【问题标题】:how to calculate the mean of a variable between two date如何计算两个日期之间变量的平均值
【发布时间】:2016-02-07 04:43:19
【问题描述】:

我想计算两个日期之间变量的平均值,下面是可重现的数据框。

year <- c(1996,1996,1996,1996,1996,1996,1996,1996,1996,1996,1996,1996,
      1996,1996,1996,1996,1996,1996,1996,1996,1996,1996,1996,1996,
      1997,1997,1997,1997,1997,1997,1997,1997,1997,1997,1997,1997,
      1997,1997,1997,1997,1997,1997,1997,1997,1997,1997,1997,1997)
month <- c("JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC")
station <- c("A","A","A","A","A","A","A","A","A","A","A","A",
         "B","B","B","B","B","B","B","B","B","B","B","B")

concentration <- as.numeric(round(runif(48,20,40),1))

df <- data.frame(year,month,station,concentration)


id <- c(1,2,3,4)
station1996 <- c("A","A","B","B")
station1997 <- c("B","A","A","B")
start <- c("06/01/1996","07/01/1996","07/01/1996","08/01/1996")
end <- c("04/01/1997","04/01/1997","04/01/1997","05/01/1997")

participant <- data.frame(id,station1996,station1997,start,end)
participant$start <- as.Date(participant$start, format = "%m/%d/%Y")
participant$end <- as.Date(participant$end, format = "%m/%d/%Y")

所以我有两个数据集如下

df
   year month station concentration
1  1996   JAN       A          24.4
2  1996   FEB       A          37.0
3  1996   MAR       A          39.5
4  1996   APR       A          28.0
...
45 1997   SEP       B          37.7
46 1997   OCT       B          35.2
47 1997   NOV       B          26.8
48 1997   DEC       B          40.0

participant
  id station1996 station1997      start        end
1  1           A           B 1996-06-01 1997-04-01
2  2           A           A 1996-07-01 1997-04-01
3  3           B           A 1996-07-01 1997-04-01
4  4           B           B 1996-08-01 1997-05-01

对于每个 id,我想计算开始日期和结束日期(月份年份)之间的平均浓度。注意到该站可能会在几年之间发生变化。

例如对于 id=1,我想计算 1996 年 6 月和 1997 年 4 月之间的平均浓度。这应该基于 1996 年 6 月到 1996 年 12 月 A 站的浓度,以及 1997 年 1 月到 1997 年 4 月在站的浓度B.

有人可以帮忙吗?

非常感谢。

【问题讨论】:

  • 第一步:将startend转换为DatePOSIXct格式,将yearmonth合并为一个相同格式的新列。
  • 您也可以将它们转换为字符串,例如“1997-10”。然后你可以像mean(concentration[date &gt;= start &amp; date &lt;= end])
  • library(zoo); as.yearmon(participant$start) 等...如果您不想处理稍微笨拙的 POSIXct 格式,在这种情况下也可能很方便。
  • 谢谢Toomet,但我需要考虑换站
  • 我已经编辑了原始问题。必须指定日期吗?虽然我只有月份和年份

标签: r date average


【解决方案1】:

这是一个 data.table 解决方案。基本思想是将开始-结束范围内的所有日期枚举为yearmon,对于每个id,然后将其用作集中表df 的索引。这有点令人费解,所以希望有人会出现并向您展示一种更简单的方法。

library(data.table)
library(zoo)          # for as.yearmon(...)
setDT(df)             # convert to data.table
setDT(participant)
df[, yrmon:= as.yearmon(paste(year,month,sep="-"), format="%Y-%B")]   # add year-month column
p.melt <- reshape(participant, varying=2:3, direction="long", sep="", timevar="year")
x <- participant[, .(date=seq(start,end,by="month")), by=id]
x[, c("year","yrmon"):=.(year(date),as.yearmon(date))]           # add year and year-month
x[p.melt, station:=station, on=c("id","year")]                   # add station
x[df, conc:= concentration, on=c("yrmon","station"), nomatch=0]  # add concentration
setorder(x,id)    # not necessary, but makes it easier to interpret x
result <- x[, .(mean.conc=mean(conc)), by=id]                    # mean(conc) by id
result
#    id mean.conc
# 1:  1  28.61818
# 2:  2  28.56000
# 3:  3  28.44000
# 4:  4  29.60000

所以,首先我们将所有内容都转换为 data.tables。然后我们在df 中添加一个yrmon 列,以便稍后进行索引。然后我们通过将participant 重塑为长格式来创建p.melt,以便该站位于一列中,而指标(1996 或 1997)位于单独的列中。然后我们创建一个临时表x,其中包含每个id 的日期序列,并为每个日期添加年份和yrmon。然后我们将其与idyear 上的p.melt 合并,以向x 添加一个站列。然后我们使用yrmonstationxdf合并,得到合适的浓度。然后我们简单地聚合conc by id in x 使用mean(...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多