【问题标题】:Aggregating in R conditional on the date在 R 中以日期为条件进行聚合
【发布时间】:2012-11-21 16:32:11
【问题描述】:

我有一些数据,我用下面的代码基于一个数据集以唯一的分钟为基础汇总信息 1 天。 但是,我希望能够使用组合了多天的数据文件来运行此代码。我在数据集中有一个日期列,因此我可以将其用作每天的唯一标识符。鉴于日期不一样,有没有办法以 1 分钟为单位汇总数据?

问题在于 unique 函数会提取第一天发生的唯一事件,然后添加在那一分钟之后发生的所有相同事件。如果我也基于日期,我相信我可以在一个长数据集中为每一天创建唯一的 1 分钟条目。

以下是适用于单日数据的代码。

novo <- read.csv("C:/Users/Morten/Desktop/data.csv", header = TRUE, stringsAsFactors=FALSE  )

TimeStamp <- novo[,1]
price <- novo[, 2]
volume <- novo[,3]
nV <- sum(volume) 

MinutesFloor <- unique(floor(TimeStamp))
nTradingMinutes <- length(MinutesFloor)

PriceMin <- rep(0, nTradingMinutes)
VolumeMin <- rep(0, nTradingMinutes)

for( j in 1:nTradingMinutes){
    ThisMinutes <- (floor(TimeStamp) == MinutesFloor[j])
    PriceMin[j] <- mean(price[ThisMinutes])
    VolumeMin[j] <- sum(volume[ThisMinutes])

    }

提前致谢

数据格式:

date,"ord","shares","finalprice","time","stock"
20100301,C,80,389,540.004,1158
20100301,C,77,389,540.004,1158
20100301,C,60,389,540.004,1158
20100301,C,28,389,540.004,1158
20100301,C,7,389,540.004,1158
20100302,C,25,394.7,540.00293333,1158
20100302,C,170,394.7,540.00293333,1158
20100302,C,40,394.7,540.00293333,1158
20100302,C,75,394.7,540.00293333,1158
20100302,C,100,394.7,540.00293333,1158
20100302,C,1,394.7,540.00293333,1158

【问题讨论】:

  • 请提供几行数据集。试试?头
  • 我在 OP 中添加了一段数据集

标签: r time


【解决方案1】:

我想建议您的代码的一个彻底简化的版本。

您正在做很多相当低效的事情。 R 用于计算由不同数据值聚类的汇总统计信息。 我们将大量使用这种方法。

我假设您的数据采用您提供的形式。在我的系统中,这看起来像

novo <- read.csv("test.csv", header = TRUE, stringsAsFactors=FALSE  )

这给了我们:

> str(novo)
'data.frame':   11 obs. of  6 variables:
 $ date      : int  20100301 20100301 20100301 20100301 20100301 20100302 20100302 20100302 20100302 20100302 ...
 $ ord       : chr  "C" "C" "C" "C" ...
 $ shares    : int  80 77 60 28 7 25 170 40 75 100 ...
 $ finalprice: num  389 389 389 389 389 ...
 $ time      : num  540 540 540 540 540 ...
 $ stock     : int  1158 1158 1158 1158 1158 1158 1158 1158 1158 1158 ...

现在,我假设您的日期是 YearMonthDate。如果您有不同的顺序,则必须更改下面的格式命令。此外,您的time 可能在几分钟内。

然后我们可以使用POSIXct 数据类型创建包含日期和时间的时间戳:

timestamps <- as.POSIXct(as.character(novo$date), format='%Y%m%d') + novo$time*60

现在,我们通过创建一个因子变量并使用cut 函数对分钟进行四舍五入:

timestampsByMinute <- droplevels(cut(timestamps, 'min'))

请注意,附加的droplevels 函数只是删除了没有可用数据项的分钟。

最后,我们可能会计算您在for-loop 中所做的汇总统计:

tapply 是一个函数,它接受它的第一个参数,将它分成由第二个参数定义的组,并将作为第三个参数给出的函数应用于该数据。因此,我们可能只是在您的数据上抛出tapply 函数。 (我觉得您在代码中使用的列号与示例数据中的列名不匹配 - 如果我以错误的方式解释您的意思,请随时适应不同的列)

PriceMin <-  tapply(novo$finalprice, timestampsByMinute, mean)
VolumeMin <- tapply(novo$shares, timestampsByMinute, sum)

这给了我们

> PriceMin
2010-03-01 09:00:00 2010-03-02 09:00:00 
              389.0               394.7 
> VolumeMin
2010-03-01 09:00:00 2010-03-02 09:00:00 
                252                 411

这可能是你想要的。

请注意,tapply 比您使用的循环快得多。如果您有巨大的数据文件,这可能很重要。

我希望我的代码中没有任何错误 - 鉴于您每天只提供一分钟的数据,因此测试并不容易。


编辑:

根据要求,这里做一个小的修改,从数据中删除时间信息:

> unname(VolumeMin)
[1] 252 411

> unname(PriceMin)
[1] 389.0 394.7

【讨论】:

  • 感谢您的帮助。尝试运行此命令时,我在 timestampsByMinute
  • @user1554592 啊,愚蠢的我……dates 当然应该是Timestamps。我在上面更正了我的答案。
  • 感谢您的帮助。但是,我需要 VolumeMin 和 PriceMin 是独立的向量,并且在数组的同一列中没有时间和日期。我在此聚合后的算法中使用 VolumeMin 和 PriceMin,因此它们需要与日期和时间戳分开。我尝试改变 tapply 以简化 = FALSE,但这并没有成功。
  • @user1554592 日期和时间戳是具有命名元素的向量。它们可以像没有附加时间信息一样使用。请注意,从统计意义上讲,您永远不会独立于收集它们的时间。你只能把信息扔掉,建议某种独立性。如果这真的是你想要的,你总是可以做到unname(VolumeMin)unname(PriceMin)
  • 是否可以创建一个长度为 (VolumeMin) 的向量并简单地在每行中生成每分钟的总和?每行代表增加一分钟?
猜你喜欢
  • 1970-01-01
  • 2020-04-16
  • 1970-01-01
  • 2020-12-24
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多