对于循环 - 从日期列中选择时间窗口

时间:2016-07-15 10:41:21

标签: r for-loop time dataframe window

我需要调整一个代码,它与我的数据框完美配合(但是使用另一个设置),以便从列Day中选择2天的时间窗口。特别是我对前一天的0天感兴趣(即i - 1和i,其中i是感兴趣的日子)并且列中包含的其(i - 1)值必须被添加到第0天(i col col。

这是我的数据框的一个例子:

我的输出应该是:

<div class="container">
<div class="row-fluid">
  <div class="col-md-12 header">

我正在尝试使用此代码,但它并不适用于我的真实数据框:

.header {
  border-bottom: 2px solid black;
  margin-top: 5px;
  margin-bottom: 5px;
}

.col-sm-6 > div {
  border: 1px solid black;
}

.section-1 {
}

.section-2 {
}

.content {
  background-color: lightgray;
}

代码似乎是正确的,它有意义,但我的输出不是。

任何人都可以帮助我吗?

@aichao代码效果很好。

如果我想考虑过去的30天(即第30天,第29天,第28天,......,第1天,第0天)有任何快速的方法来做,而不是创建30个if语句(条件)?

再次感谢@aichao的帮助。

1 个答案:

答案 0 :(得分:1)

以下是您对所提供的样本数据所需的内容

for (i in unique(df$Day)) {
  temp <- df$Count[df$Day == i]
  if (any(temp > 0)) {
    condition1 <- df$Day == i - 1
    condition1[which(df$Day == i - 1) < max(which(df$Day == i))] <- FALSE
    if (any(condition1)) {
      df$Count[df$Day == i] <- mean(df$Count[condition1]) + df$Count[df$Day == i]
      df$Count[condition1] <- 0
    }
  }
}
print(df[order(df$Count, decreasing = TRUE),])
##   Station   Day Count
##1    33012 12448     7
##2    35004 12448     7
##3    35008 12448     7
##4    37006 12448     7
##5    21009  4835     5
##6    24005  4835     5
##7    27001  4835     5
##11   29002 12446     4
##12   30001 12446     4
##13   31002 12446     4
##17   51001 12449     1
##18   51003  4832     1
##19   52004  4836     1
##8    25005 12447     0
##9    29001 12447     0
##10   29002 12447     0
##14   47007  4834     0
##15   49002  4834     0
##16   47004 12445     0

从您的实施中遗漏的评论中发现的关键要求是,在确定前一天及其计数时,只考虑数据框下方(行数)的几天。也就是说,您正在处理数据框行,就像它们是按时排序一样,而不是将Day列中的值视为时间顺序。因此,对于df$Day = 12449,没有前一天要考虑,因为df$Day = 12448之前的所有行都在它之前。因此,Count的{​​{1}}保持为df$Day = 12449,更重要的是,1的所有行的Counts都不会归零处理df$Day = 12448后。

为了实现这一点,我们需要进一步过滤df$Day = 12449,以便我们将condition1所有行FALSE(前一天)设置为最高行{{1} (感兴趣的一天)使用

df$Day == i - 1

请注意,此解决方案假定数据框中df$Day == i列的相同值作为样本数据中的行块集中在一起。否则,您的condition1[which(df$Day == i - 1) < max(which(df$Day == i))] <- FALSE 循环Day需要完全重新考虑并替换为行循环,以便跟踪数据框中感兴趣日的当前行。

此外,您的代码中存在一个小错误

for

目的是检查感兴趣的日期unique(df$Day)是否大于if(length(temp > 0)) { 的行。但是,R中的条件运算符被向量化,使Count返回与其输入0长度相同的布尔向量。因此,temp > 0将始终返回正数,除非temp本身的长度为length(temp > 0)(即为空)。要获得您的意图,该行将更改为

temp

更新:有关前几天的新要求

解决新要求的最简单方法是将0块中的代码体放入函数中,将其称为if(any(temp > 0)) { ,并使用{在前几天的集合中应用此函数{1}}。修改是:

if (any(temp > 0)) {...}

注意:

  1. accumulate.mean.count是当前日期之前(即,滞后)的天数。 sapply表示前一天,accumulate.mean.count <- function(this.day, lag) { condition1 <- df$Day == this.day - lag condition1[which(df$Day == this.day - lag) < max(which(df$Day == this.day))] <- FALSE if (any(condition1)) { df$Count[df$Day == this.day] <<- mean(df$Count[condition1]) + df$Count[df$Day == this.day] df$Count[condition1] <<- 0 } } lags <- seq_len(30) for (i in unique(df$Day)) { temp <- df$Count[df$Day == i] if (any(temp > 0)) { sapply(lags, accumulate.mean.count, this.day=i) } } print(df[order(df$Count, decreasing = TRUE),]) 表示前两天,等等。lag是这些的集合。在此处,lag = 1是从lag = 2lags的序列,应用了lags <- seq_len(30),这就是您想要的。有关1 R系列函数的精彩概述,请参阅this。请注意,30不一定是一个序列,而只是前一天,前一天前一天和前一天前一天的accumulate.mean.count整数集合。如果你想在未来几天滚动,它甚至不必是积极的,但不应该是零。

  2. 由于lexical scoping rule of R,设置*apply,这是lags范围之外的变量,因此c(1, 5, 10)函数需要df$Count而不是accumulate.mean.count。请参阅this以获取解释,并注意使用accumulate.mean.count时提到的危险。

  3. 我没有足够的数据来测试<<-,但对于<-,我恢复了原始结果,对于<<-,我得到了

    lags <- seq_len(30)

    我认为这就是你想要的。