如何在R中创建条件虚拟?
我有一个时间序列数据的数据框架,包含每日的温度观测数据。我需要创建一个虚拟变量,对温度高于5摄氏度阈值的每一天进行计数。这本身就很容易,但存在一个附加条件:只有在连续超过阈值十天后才开始计数。下面是一个数据帧示例:如何在R中创建条件虚拟?,r,loops,dataframe,R,Loops,Dataframe,我有一个时间序列数据的数据框架,包含每日的温度观测数据。我需要创建一个虚拟变量,对温度高于5摄氏度阈值的每一天进行计数。这本身就很容易,但存在一个附加条件:只有在连续超过阈值十天后才开始计数。下面是一个数据帧示例: df <- data.frame(date = seq(365), temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365)) df这里有一个使用rle的基本R选项: df$dummy <
df <- data.frame(date = seq(365),
temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365))
df这里有一个使用rle的基本R选项:
df$dummy <- with(rle(df$temp > 5), rep(as.integer(values & lengths >= 10), lengths))
现在我们想找出值为真(即temp大于5)且长度大于10(即至少十个连续temp
值大于5)的情况。我们通过运行以下命令来实现此目的:
values & lengths >= 10
最后,由于我们希望返回与nrow(df)
长度相同的向量,因此我们使用rep(…,length)
和as.integer
为了返回1/0而不是TRUE
/FALSE
我认为您可以使用简单的ifelse和。最后一步只是填充结果,以说明前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)
图书馆(动物园)
df我会这样做:
set.seed(42)
df <- data.frame(date = seq(365),
temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365))
thr <- 5
df$dum <- 0
#find first 10 consecutive values above threshold
test1 <- filter(df$temp > thr, rep(1,10), sides = 1) == 10L
test1[1:9] <- FALSE
n <- which(cumsum(test1) == 1L)
#count days above threshold after that
df$dum[(n+1):nrow(df)] <- cumsum(df$temp[(n+1):nrow(df)] > thr)
set.seed(42)
df将函数(x){sum(x)}
替换为一个简单的sum
?建议这样写:df2 5),head=rollsum(uncd,10,align=“left”,fill=0)==10,tail=rollsum(uncd,10,align=“right”,fill=0)==10)+0,但这是最简单的,如果存在的话,我倾向于使用R基解。谢谢您可能需要仔细检查此解决方案。我在第67-75天得到了虚拟值=1,尽管这些天不是连续10天>5度运行的一部分temps@JHowIX,你能举个例子吗?请注意,样本数据使用rnorm
而不设置种子,因此解决方案不必相同(因为样本数据可能不同)@docendodiscimus-true,我不确定我希望如何传达样本数据。但是,在同一数据帧上运行您的解决方案和我的解决方案,它们会产生不同的结果,这意味着您的或我的解决方案是不正确的。如果是我的,我想知道,这样我就可以纠正它。rle
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)
set.seed(42)
df <- data.frame(date = seq(365),
temp = -30 + 0.65*seq(365) - 0.0018*seq(365)^2 + rnorm(365))
thr <- 5
df$dum <- 0
#find first 10 consecutive values above threshold
test1 <- filter(df$temp > thr, rep(1,10), sides = 1) == 10L
test1[1:9] <- FALSE
n <- which(cumsum(test1) == 1L)
#count days above threshold after that
df$dum[(n+1):nrow(df)] <- cumsum(df$temp[(n+1):nrow(df)] > thr)