绑定新计算的“滑动”数据帧而不使用循环和rbind

时间:2017-04-03 07:23:13

标签: r loops dataframe

我有data.frameDate列以及其他一些变量,例如:

df <- data.frame(date = rep(seq.Date(as.Date("2017-01-01"), as.Date("2017-01-10"), by = "day"), 2),
             x = c(rep("a", 10), rep("b", 10)),
             y = rep(letters[3:7], each = 4),
             z = rnorm(20))

我希望在Date上“滑动”,为某个宽度的每个“窗口”计算一些新的data.frame(比如说​​所有3天的时间段),然后将它们绑定到一个新的data.frame,比如用一段句子“标识符”来知道每一行来自哪个时期,例如这个时期的第一个日期。

示例,非常漂亮/慢速的方式:

windowLength <- 3
dateVec <- df$date %>% unique %>% unlist

nonTrivialFunctionWhichCreatesANewDataFrame <- function(i) {
  df %>%
    filter(date >= dateVec[i], date <= dateVec[i + windowLength - 1]) %>%
    group_by(x, y) %>%
    summarise(zSum = sum(z), zCount = n()) %>%
    mutate(startDate = dateVec[i])
}

df2 <- NULL
for (i in 1:(length(dateVec) - windowLength + 1)) {
  dfTemp <- nonTrivialFunctionWhichCreatesANewDataFrame(i)
  df2 <- rbind(df2, dfTemp)
}

head(df2)

Source: local data frame [6 x 5]
Groups: x [2]

   x      y        zSum zCount  startDate
  <fctr> <fctr>       <dbl>  <int>     <date>
1      a      c  1.27899229      3 2017-01-01
2      b      e  1.05072378      2 2017-01-01
3      b      f -1.04083228      1 2017-01-01
4      a      c  0.67568894      3 2017-01-02
5      b      e  0.03046459      1 2017-01-02
6      b      f -1.55901277      2 2017-01-02

我尝试使用rollapply包中的zoo,首先将我的data.frame定义为时间序列对象 - 但无济于事。

什么是更快,更无循环的方法呢?

更新:为什么zoo的{​​{1}}对我不起作用

简单示例:

rollapply

正如您所看到的,因为日期不是唯一的,尽管z <- zoo(1:10, as.Date(rep(31:35, 2))) z 1970-02-01 1970-02-01 1970-02-02 1970-02-02 1970-02-03 1970-02-03 1970-02-04 1970-02-04 1970-02-05 1 6 2 7 3 8 4 9 5 1970-02-05 10 rollapply(z, width = 3, FUN = sum, align = "right") 1970-02-02 1970-02-02 1970-02-03 1970-02-03 1970-02-04 1970-02-04 1970-02-05 1970-02-05 9 15 12 18 15 21 18 24 确认重新排列数据,但sum函数仅在3行上滚动(第1个元素为1 + 6 + 2 = 9) ) - 根据需要不在3

0 个答案:

没有答案