如何在R中创建条件虚拟?

Ant*_*tti 5 loops r dataframe

我有一个时间序列数据的数据框,每天观察温度.我需要创建一个虚拟变量,计算每天温度高于5C的阈值.这本身很容易,但存在一个附加条件:计数仅在超过阈值连续十天后开始计数.这是一个示例数据帧:

df <- data.frame(date = seq(365), 
         temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365))
Run Code Online (Sandbox Code Playgroud)

我想我已经完成了,但是我喜欢的循环太多了.这就是我做的:

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)
Run Code Online (Sandbox Code Playgroud)

有谁能建议更简单的方法吗?

tal*_*lat 5

这是一个基本R选项使用rle:

df$dummy <- with(rle(df$temp > 5), rep(as.integer(values & lengths >= 10), lengths))
Run Code Online (Sandbox Code Playgroud)

一些解释:该任务是运行长度encoding(rle)函数imo 的经典用例.我们首先检查值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 ...
Run Code Online (Sandbox Code Playgroud)

现在,我们要找出那些情况下,valuesIS TRUE(即温度大于5),并在同一时间lengths大于10(即连续至少十个temp值大于5).我们这样做是通过运行:

values & lengths >= 10
Run Code Online (Sandbox Code Playgroud)

最后,因为我们想要返回一个长度相同的向量nrow(df),我们使用rep(..., lengths)as.integer返回1/0而不是TRUE/ FALSE.

  • `r`` < - 最接近的`R`必须是一把万能锤.:-) (2认同)

JHo*_*wIX 5

我认为你可以在动物园包中使用简单的ifelse和roll apply函数的组合来实现你想要的.最后一步只是将结果填充到第一个N-1天,其中没有足够的信息来填充窗口.

library(zoo)

df <- data.frame(date = seq(365), 
                 temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365))

df$above5 <- ifelse(df$temp > 5, 1, 0)
temp <- rollapply(df$above5, 10, sum)
df$conseq <- c(rep(0, 9),temp)
Run Code Online (Sandbox Code Playgroud)