我需要调整一个代码,它与我的数据框完美配合(但是使用另一个设置),以便从列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的帮助。
答案 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)) {...}
注意:
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 = 2
到lags
的序列,应用了lags <- seq_len(30)
,这就是您想要的。有关1
R系列函数的精彩概述,请参阅this。请注意,30
不一定是一个序列,而只是前一天,前一天前一天和前一天前一天的accumulate.mean.count
整数集合。如果你想在未来几天滚动,它甚至不必是积极的,但不应该是零。
由于lexical scoping rule of R,设置*apply
,这是lags
范围之外的变量,因此c(1, 5, 10)
函数需要df$Count
而不是accumulate.mean.count
。请参阅this以获取解释,并注意使用accumulate.mean.count
时提到的危险。
我没有足够的数据来测试<<-
,但对于<-
,我恢复了原始结果,对于<<-
,我得到了
lags <- seq_len(30)
我认为这就是你想要的。