通过基于多个条件对行进行求和来在R中创建向量

时间:2016-01-17 01:58:36

标签: r criteria sumifs

我的财务数据目前间隔为15分钟,但我想在进行剩余分析之前将时间间隔从15分钟转换为30分钟。因此,我想对两个相邻的15分钟间隔的交易量进行求和,并取第二个15分钟子间隔的收盘价(即30分钟期间的结束时间)。

我在下面显示了使用sapply函数的数据(df)和所需输出(df.30min)的示例。这适用于下面的示例,但考虑到我正在分析10个公司的每日数据,每天有10个公司和27个间隔,处理时间过长,即使是一年的数据。如果我尝试for循环,我有类似的问题。

我是R的新手,所以我希望使用其中一个内置函数有一个相当简单的解决方案。

在我的实际数据集中,有27 x 15分钟的间隔(10:00-16:45)。我想要我的最后一次" 30分钟"数据集与13:30-13:45之间有15分钟的间隔。此外,可能存在其他异常现象,即证券交易所提前开盘/早盘关闭,或者股票在一天中途停止交易。 (我已经设法使用具有匹配函数的查找表将我的数据中的时间映射到正确的Interval。)鉴于我的数据结构不完美,我的解决方案不依赖于完整集合,并且完全偶数15分钟的间隔。在Excel中我会使用sumifs函数。

set.seed(1)
df <- data.frame(
  Company = rep(c("Co A", "Co B", "Co C"), each = 8),
  Date = as.Date(rep(c("2005-01-01", "2005-01-02"), times = 3, each = 4)),
  Time = as.factor(c("10:00:00", "10:15:00", "10:30:00", "10:45:00")),
  Interval = as.factor(c(1,1,2,2)),
  Interval.End = as.factor(c(0,1)),
  Close = abs(round(rnorm(24),1))*10+100,
  Volume = abs(round(rnorm(24),1))*10)

> df
   Company       Date     Time Interval Interval.End Close Volume
1     Co A 2005-01-01 10:00:00        1            0   106      6
2     Co A 2005-01-01 10:15:00        1            1   102      1
3     Co A 2005-01-01 10:30:00        2            0   108      2
4     Co A 2005-01-01 10:45:00        2            1   116     15
5     Co A 2005-01-02 10:00:00        1            0   103      5
6     Co A 2005-01-02 10:15:00        1            1   108      4
7     Co A 2005-01-02 10:30:00        2            0   105     14
8     Co A 2005-01-02 10:45:00        2            1   107      1
9     Co B 2005-01-01 10:00:00        1            0   106      4
10    Co B 2005-01-01 10:15:00        1            1   103      1
11    Co B 2005-01-01 10:30:00        2            0   115     14
12    Co B 2005-01-01 10:45:00        2            1   104      4
13    Co B 2005-01-02 10:00:00        1            0   106      4
14    Co B 2005-01-02 10:15:00        1            1   122      1
15    Co B 2005-01-02 10:30:00        2            0   111     11
16    Co B 2005-01-02 10:45:00        2            1   100      8
17    Co C 2005-01-01 10:00:00        1            0   100      2
18    Co C 2005-01-01 10:15:00        1            1   109      3
19    Co C 2005-01-01 10:30:00        2            0   108      7
20    Co C 2005-01-01 10:45:00        2            1   106      6
21    Co C 2005-01-02 10:00:00        1            0   109      7
22    Co C 2005-01-02 10:15:00        1            1   108      7
23    Co C 2005-01-02 10:30:00        2            0   101      4
24    Co C 2005-01-02 10:45:00        2            1   120      8

df.30min <- df[-which(df$Interval.End == 0),]

df.30min$Volume <-sapply(seq_len(nrow(df.30min)),
            function(i) sum(df$Volume[df$Company == df.30min$Company[i] &
                                        df$Date == df.30min$Date[i] &
                                        df$Interval == df.30min$Interval[i]]))

> df.30min
   Company       Date     Time Interval Interval.End Close Volume
2     Co A 2005-01-01 10:15:00        1            1   102      7
4     Co A 2005-01-01 10:45:00        2            1   116     17
6     Co A 2005-01-02 10:15:00        1            1   108      9
8     Co A 2005-01-02 10:45:00        2            1   107     15
10    Co B 2005-01-01 10:15:00        1            1   103      5
12    Co B 2005-01-01 10:45:00        2            1   104     18
14    Co B 2005-01-02 10:15:00        1            1   122      5
16    Co B 2005-01-02 10:45:00        2            1   100     19
18    Co C 2005-01-01 10:15:00        1            1   109      5
20    Co C 2005-01-01 10:45:00        2            1   106     13
22    Co C 2005-01-02 10:15:00        1            1   108     14
24    Co C 2005-01-02 10:45:00        2            1   120     12

2 个答案:

答案 0 :(得分:0)

使用库dplyr,你可以尝试这样的事情:

library(dplyr)
df %>% arrange(Company, Date, Time, Interval, Interval.End) %>% group_by(Company, Date, Interval) %>% summarise(Time = Time[2], Interval.End = Interval.End[2], Close = Close[2], Volume = sum(Volume))
Source: local data frame [12 x 7]
Groups: Company, Date [?]

   Company       Date Interval     Time Interval.End Close Volume
    (fctr)     (date)   (fctr)   (fctr)       (fctr) (dbl)  (dbl)
1     Co A 2005-01-01        1 10:15:00            1   102      7
2     Co A 2005-01-01        2 10:45:00            1   116     17
3     Co A 2005-01-02        1 10:15:00            1   108      9
4     Co A 2005-01-02        2 10:45:00            1   107     15
5     Co B 2005-01-01        1 10:15:00            1   103      5
6     Co B 2005-01-01        2 10:45:00            1   104     18
7     Co B 2005-01-02        1 10:15:00            1   122      5
8     Co B 2005-01-02        2 10:45:00            1   100     19
9     Co C 2005-01-01        1 10:15:00            1   109      5
10    Co C 2005-01-01        2 10:45:00            1   106     13
11    Co C 2005-01-02        1 10:15:00            1   108     14
12    Co C 2005-01-02        2 10:45:00            1   120     12

如果您的数据框已经正确排列,您可以摆脱上面的arrange部分。

注意:我假设总有两个间隔(0,1),因此使用2的硬编码值。如果不是这种情况,您可以使用正确的子集。

答案 1 :(得分:0)

我们可以使用data.table

执行此操作
library(data.table)
setDT(df)[order(Company, Date, Time, Interval),
     list(Time=Time[2L],  Interval.End = Interval.End[2L],
          Close = Close[2L], Volume = sum(Volume)),
               by = .(Company, Date, Interval)]
#     Company       Date Interval     Time Interval.End Close Volume
# 1:    Co A 2005-01-01        1 10:15:00            1   102      7
# 2:    Co A 2005-01-01        2 10:45:00            1   116     17
# 3:    Co A 2005-01-02        1 10:15:00            1   108      9
# 4:    Co A 2005-01-02        2 10:45:00            1   107     15
# 5:    Co B 2005-01-01        1 10:15:00            1   103      5
# 6:    Co B 2005-01-01        2 10:45:00            1   104     18
# 7:    Co B 2005-01-02        1 10:15:00            1   122      5
# 8:    Co B 2005-01-02        2 10:45:00            1   100     19
# 9:    Co C 2005-01-01        1 10:15:00            1   109      5
#10:    Co C 2005-01-01        2 10:45:00            1   106     13
#11:    Co C 2005-01-02        1 10:15:00            1   108     14
#12:    Co C 2005-01-02        2 10:45:00            1   120     12