R filtering/selecting data by POSIXct time and a condition
R filtering/selecting data by POSIXct time and a condition
我已经在不同的城市树种上以 10 分钟的高时间分辨率测量了温度,应该比较它们的反应。因此,我正在研究特别热的时期。我无法对我的数据集执行的任务是从最大值中选择完整的天数。例如。有一个高于 30 °C 的测量值的日子应该从我的数据框中完全被子集化。
您在下面找到一个可以说明我的问题的可重现示例:
在我的 Measurings
数据框中,我计算了一个列,指示单个测量值是高于还是低于 30°C。我想使用该列来告诉其他函数他们是否应该选择一天来生成 New Dataframe
。当一天中的任何时候该值高于 30°C 时,我想按 00:00 到 23:59 的日期将其包含在 New Dataframe
中以供进一步分析。
start <- as.POSIXct("2018-05-18 00:00", tz = "CET")
tseq <- seq(from = start, length.out = 1000, by = "hours")
Measurings <- data.frame(
Time = tseq,
Temp = sample(20:35,1000, replace = TRUE),
Variable1 = sample(1:200,1000, replace = TRUE),
Variable2 = sample(300:800,1000, replace = TRUE)
)
Measurings$heat30 <- ifelse(Measurings$Temp > 30,"heat", "normal")
Measurings$otheroption30 <- ifelse(Measurings$Temp > 30,"1", "0")
该示例正在生成一个类似于我的数据结构的数据帧:
head(Measurings)
Time Temp Variable1 Variable2 heat30 otheroption30
1 2018-05-18 00:00:00 28 56 377 normal 0
2 2018-05-18 01:00:00 23 65 408 normal 0
3 2018-05-18 02:00:00 29 78 324 normal 0
4 2018-05-18 03:00:00 24 157 432 normal 0
5 2018-05-18 04:00:00 32 129 794 heat 1
6 2018-05-18 05:00:00 25 27 574 normal 0
那么我如何子集得到一个 New Dataframe
其中所有的日子都是至少有一个条目表示为"heat"?
我知道 dplyr:filter
可以过滤单个条目(示例开头的第 5 行)。 但是我怎么知道要花一整天 2018-05-18?
我对使用 R 分析数据还很陌生,所以我很感激任何关于我的问题的有效解决方案的建议。 dplyr
这是我在很多任务中一直使用的,但我对任何有用的东西都持开放态度。
非常感谢,康拉德
以下是使用问题中提供的数据集的一种可能解决方案。请注意,这不是一个很好的例子,因为所有日子 可能 都包括至少一个标记为超过 30 °C 的观测值(即在该数据集中没有要过滤掉的日子,但代码应该用实际的代码完成工作)。
# import packages
library(dplyr)
library(stringr)
# break the time stamp into Day and Hour
time_df <- as_data_frame(str_split(Measurings$Time, " ", simplify = T))
# name the columns
names(time_df) <- c("Day", "Hour")
# create a new measurement data frame with separate Day and Hour columns
new_measurings_df <- bind_cols(time_df, Measurings[-1])
# form the new data frame by filtering the days marked as heat
new_df <- new_measurings_df %>%
filter(Day %in% new_measurings_df$Day[new_measurings_df$heat30 == "heat"])
更准确地说,您正在创建一个随机样本,其中包含 40 天内温度在 20 到 35 之间变化的 1000 个观测值。因此,在您的示例中,很可能每一天至少有一次观测值被标记为超过 30 °C。此外,设置种子以确保 reproducibility 始终是一个好习惯。
创建指定哪一天的变量(删除小时、分钟等)。遍历唯一日期,只取 heat30 中至少包含 "heat" 一次的子集:
Measurings <- Measurings %>% mutate(Time2 = format(Time, "%Y-%m-%d"))
res <- NULL
newdf <- lapply(unique(Measurings$Time2), function(x){
ss <- Measurings %>% filter(Time2 == x) %>% select(heat30) %>% pull(heat30) # take heat30 vector
rr <- Measurings %>% filter(Time2 == x) # select date x
# check if heat30 vector contains heat value at least once, if so bind that subset
if(any(ss == "heat")){
res <- rbind(res, rr)
}
return(res)
}) %>% bind_rows()
我已经在不同的城市树种上以 10 分钟的高时间分辨率测量了温度,应该比较它们的反应。因此,我正在研究特别热的时期。我无法对我的数据集执行的任务是从最大值中选择完整的天数。例如。有一个高于 30 °C 的测量值的日子应该从我的数据框中完全被子集化。 您在下面找到一个可以说明我的问题的可重现示例:
在我的 Measurings
数据框中,我计算了一个列,指示单个测量值是高于还是低于 30°C。我想使用该列来告诉其他函数他们是否应该选择一天来生成 New Dataframe
。当一天中的任何时候该值高于 30°C 时,我想按 00:00 到 23:59 的日期将其包含在 New Dataframe
中以供进一步分析。
start <- as.POSIXct("2018-05-18 00:00", tz = "CET")
tseq <- seq(from = start, length.out = 1000, by = "hours")
Measurings <- data.frame(
Time = tseq,
Temp = sample(20:35,1000, replace = TRUE),
Variable1 = sample(1:200,1000, replace = TRUE),
Variable2 = sample(300:800,1000, replace = TRUE)
)
Measurings$heat30 <- ifelse(Measurings$Temp > 30,"heat", "normal")
Measurings$otheroption30 <- ifelse(Measurings$Temp > 30,"1", "0")
该示例正在生成一个类似于我的数据结构的数据帧:
head(Measurings)
Time Temp Variable1 Variable2 heat30 otheroption30
1 2018-05-18 00:00:00 28 56 377 normal 0
2 2018-05-18 01:00:00 23 65 408 normal 0
3 2018-05-18 02:00:00 29 78 324 normal 0
4 2018-05-18 03:00:00 24 157 432 normal 0
5 2018-05-18 04:00:00 32 129 794 heat 1
6 2018-05-18 05:00:00 25 27 574 normal 0
那么我如何子集得到一个 New Dataframe
其中所有的日子都是至少有一个条目表示为"heat"?
我知道 dplyr:filter
可以过滤单个条目(示例开头的第 5 行)。 但是我怎么知道要花一整天 2018-05-18?
我对使用 R 分析数据还很陌生,所以我很感激任何关于我的问题的有效解决方案的建议。 dplyr
这是我在很多任务中一直使用的,但我对任何有用的东西都持开放态度。
非常感谢,康拉德
以下是使用问题中提供的数据集的一种可能解决方案。请注意,这不是一个很好的例子,因为所有日子 可能 都包括至少一个标记为超过 30 °C 的观测值(即在该数据集中没有要过滤掉的日子,但代码应该用实际的代码完成工作)。
# import packages
library(dplyr)
library(stringr)
# break the time stamp into Day and Hour
time_df <- as_data_frame(str_split(Measurings$Time, " ", simplify = T))
# name the columns
names(time_df) <- c("Day", "Hour")
# create a new measurement data frame with separate Day and Hour columns
new_measurings_df <- bind_cols(time_df, Measurings[-1])
# form the new data frame by filtering the days marked as heat
new_df <- new_measurings_df %>%
filter(Day %in% new_measurings_df$Day[new_measurings_df$heat30 == "heat"])
更准确地说,您正在创建一个随机样本,其中包含 40 天内温度在 20 到 35 之间变化的 1000 个观测值。因此,在您的示例中,很可能每一天至少有一次观测值被标记为超过 30 °C。此外,设置种子以确保 reproducibility 始终是一个好习惯。
创建指定哪一天的变量(删除小时、分钟等)。遍历唯一日期,只取 heat30 中至少包含 "heat" 一次的子集:
Measurings <- Measurings %>% mutate(Time2 = format(Time, "%Y-%m-%d"))
res <- NULL
newdf <- lapply(unique(Measurings$Time2), function(x){
ss <- Measurings %>% filter(Time2 == x) %>% select(heat30) %>% pull(heat30) # take heat30 vector
rr <- Measurings %>% filter(Time2 == x) # select date x
# check if heat30 vector contains heat value at least once, if so bind that subset
if(any(ss == "heat")){
res <- rbind(res, rr)
}
return(res)
}) %>% bind_rows()