我有一个时间序列数据的数据框,其中包含每日温度观测值。我需要创建一个虚拟变量,对温度高于阈值 5C 的每一天进行计数。这本身很容易,但存在一个附加条件:仅在连续十天高于阈值后才开始计数。这是一个示例数据框:
df <- data.frame(date = seq(365),
temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365))
我想我已经完成了,但是我喜欢的循环太多了。这就是我所做的:
df$dummyUnconditional <- 0
df$dummyHead <- 0
df$dummyTail <- 0
for(i in 1:nrow(df)){
if(df$temp[i] > 5){
df$dummyUnconditional[i] <- 1
}
}
for(i in 1:(nrow(df)-9)){
if(sum(df$dummyUnconditional[i:(i+9)]) == 10){
df$dummyHead[i] <- 1
}
}
for(i in 9:nrow(df)){
if(sum(df$dummyUnconditional[(i-9):i]) == 10){
df$dummyTail[i] <- 1
}
}
df$dummyConditional <- ifelse(df$dummyHead == 1 | df$dummyTail == 1, 1, 0)
谁能建议更简单的方法来做到这一点?
这是一个基本的 R 选项,使用rle
:
df$dummy <- with(rle(df$temp > 5), rep(as.integer(values & lengths >= 10), lengths))
一些解释:该任务是游程编码的经典用例(rle
)函数,我认为。我们首先检查temp
大于 5(创建逻辑向量)并应用rle
在该向量上导致:
> rle(df$temp > 5)
#Run Length Encoding
# lengths: int [1:7] 66 1 1 225 2 1 69
# values : logi [1:7] FALSE TRUE FALSE TRUE FALSE TRUE ...
现在我们想要找到那些案例values
is TRUE
(即温度大于 5)并且同时lengths
大于 10(即至少连续十个temp
值大于 5)。我们通过运行以下命令来做到这一点:
values & lengths >= 10
最后,因为我们想要返回一个与以下长度相同的向量nrow(df)
, 我们用rep(..., lengths)
and as.integer
为了返回 1/0 而不是TRUE
/FALSE
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)