我在R中处理由时间和降水数据组成的数据框(超过3 000 000个值,每分钟测量)
我想提取所有"降水事件",这些事件实际上是下雨时的所有时刻(dp != 0,但也包括可能下雨的中断,但不再是下一次测量的"a")
我希望所有剧集都存储在新的数据框中,并带有附加列,其中包含每个剧集的数量。第一场雨 - 1,第二次 - 2....
"降水事件"的例子:
time <- c("2013-01-01 11:39:00",
"2013-01-01 11:40:00", "2013-01-01 11:41:00",
"2013-01-01 11:42:00","2013-01-01 11:43:00",
"2013-01-01 11:44:00","2013-01-01 11:45:00",
"2013-01-01 11:46:00","2013-01-01 11:47:00",
"2013-01-01 11:48:00","2013-01-01 11:49:00",
"2013-01-01 11:50:00","2013-01-01 11:51:00",
"2013-01-01 11:52:00","2013-01-01 11:53:00")
time <- as.POSIXct(time , origin="1899-12-30",tz="GMT")
p<- c(1.565, 1.565, 1.658, 1.795, 1.795, 1.795, 1.896, 1.896, 2.985, 2.985,
2.985, 2.985, 3.5, 3.7, 3.85)
df <- data.frame(time, p)
dp <- diff(df$p)
df$dp<- c(dp,0)
我使用 for 循环和(很多)if 条件创建了一个函数,我希望这能很好地代表我的意图。它目前运行不佳 - 仍在寻找原因。
rain.episodes<- function(x) {
a<- 300
episode.number <- 1
rain <- reja.clean[1,] #just for column names
for (i in 1:nrow(x)) {
if (x[i,"dp"] >0) {
rain[i,]<- x[i,]
rain[i, "episode.number"]<- episode.number
a<-0
} else if (x[i,"dp"] ==0 & a<300) {
rain[i,]<- x[i,]
rain[i, "episode.number"]<- episode.number
a<-a+1
} else if (a==301) {
episode.number<-episode.number+1
} else{
a<-a+1
}
}
return(rain)
}
有没有办法创建一个函数来帮助我解决这个问题,输出与我粘贴的输出相同,但使用不同的(更好)方法?
我还想知道为什么我的函数不起作用。
这可能有效:
#load libraries
library(dplyr)
library(lubridate)
library(zoo) # for `na.locf`
library(data.table) # for Step 2
第 1 步:识别下雨/不下雨的情节:真/假
df_new <- df[-1,] %>% #remove the first non-rainy observation to suit `na.locf`**
arrange(time) %>%
# create ind_hour to keep the time when it rained
mutate(ind_hour = ifelse (dp != 0, format(as.POSIXct(time) ,format = "%Y-%m-%d %H:%M:%S"), NA)) %>%
# when it did not rain (i.e. ind_hour is NA), add an extra hour to the last known time when it rained (use na.locf to get the last time when it rained)
mutate(ind_hour_complete = ifelse(is.na(ind_hour), (na.locf(as.POSIXct(ind_hour, format = "%Y-%m-%d %H:%M:%S", tz="GMT")) + hours(1)), time)) %>%
# if `time` is lower or equal to the `ind_hour_complete`, then we are looking at the same episode
mutate(same_episode = time <= ind_hour_complete) %>%
select(-ind_hour, -ind_hour_complete)
**注意:在以NA
开头的向量中,na.locf
将删除它,并且生成的向量将具有长度(n-1)
。在这里,结果将向上移动一行。您可以在不从df
中删除第一行的情况下尝试代码,以了解我的意思。如果需要,您可以在最后添加第一行,ep_number
等于 max(df_new$ep_number) + 1
(以确保ep_number
是唯一的)。我已经完全删除了它,因为您似乎不需要它(根据您的预期输出)。
第 2 步:为已识别的剧集添加索引:ep_number
df_new <- setDT(df_new)[, ep_number:= rleid(same_episode)]