【问题标题】:How to calculate a condition using dplyr?如何使用 dplyr 计算条件?
【发布时间】:2021-10-12 06:22:14
【问题描述】:

我想使用dplyr计算以下条件

a) 当正常最低温度等于 10°C 或更高时。

寒潮:偏离正常为 -5°C 至 -6°C。

严重寒潮:偏离正常为 -7°C 或更低

b) 正常最低温度低于 10°C 时。

寒潮:偏离正常为 -4°C 至 -5°C。

严重寒潮:偏离正常为 -6°C 或更低。

我正在使用以下代码

library(tidyverse)

set.seed(123)
df <- data.frame("Date"= seq(from = as.Date("1970-1-1"), to = as.Date("2000-12-31"), by = "day"),
                 "Station1" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 10, 30),
                 "Station2" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 11, 29),
                 "Station3" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 8, 28))

#Calculation of normal minimum temperature 
df_summarise_all <- df %>% 
  as_tibble() %>% # for easier viewing 
  mutate(day = format(as.Date(df$Date, format='%Y-%m-%d'), format='%m-%d')) %>% 
  group_by(day) %>%
  summarise_all(list(mean)) %>% 
  pivot_longer(cols = -c(Date, day), names_to = "variable", values_to = "value")

#Identification of days fulfilling the condition for cold wave
df_out <- df %>%
  as_tibble() %>% # for easier viewing 
  mutate(day = format(as.Date(df$Date, format='%Y-%m-%d'), format='%m-%d')) %>%
  tidyr::pivot_longer(cols = -c(Date, day), 
                      names_to = "Stations", values_to = "MinT") %>%
  left_join(df_summarise_all %>% rename(mean_MinT = value), 
            by = c('day' = 'day', 'Stations' = 'variable')) %>%
  mutate(is_coldwave = zoo::rollapplyr(MinT < (ifelse(mean_MinT < 10, mean_MinT - 4, mean_MinT - 5)), 
                                       1, all, fill = NA))

我无法实现 -5°C 到 -6°C 和 -4°C 到 -5°C 的条件。如何使用dplyr 实现这一点?

【问题讨论】:

  • 1.正常最低温度是多少? 2. 如果您提供一小部分数据并显示其预期输出,则更容易理解问题。 3. 我不清楚你为什么在这里使用zoo::rollapplyr
  • 1.正常最低温度是多年每日最低温度数据的每日平均值。 2. 当条件满足时,它应该返回 TRUE,否则返回 FALSE。 3. 我从您的previous answer 中使用过它。
  • 您能否再解释一下您期望获得的数据子集的结果是什么?当我运行代码时,小于mean_MinT 所需数量的minT 值被标记为TRUE,所有其他值都是FALSE,根据描述,这似乎是正确的。
  • @Tjn25 我无法实现 -5°C 到 -6°C 和 -4°C 到 -5°C 的条件。我可以将条件应用为mean_MinT - 4, mean_MinT - 5,但是-6 和-5 呢?
  • 我对所提供问题的解释是 -6C 或更低的偏离是严重的,但如果它们至少是 -4(包括 -4.0 到 -4.999),那只是一个寒潮。所以嵌套的 ifelse 只需要与 mean_MinT - 4 进行比较。

标签: r dplyr tidyverse


【解决方案1】:

据我了解,您需要一列检查温度是否偏离 5 到 6 度(如果温度大于 10 度),另一列检查温度是否相差 7 度或更多。

您当前使用的代码似乎可以正确识别 coldwave 值,但也包括 severe_coldwave 值。

您可以添加另一个恶劣天气检查,类似于已编码的内容,如果天气恶劣,请将任何 is_coldwave 值设置为 FALSE

这会将偏离 5-6.5 度的值设置为is_coldwave,并将大于 6.5 的值设置为is_severe_coldwave

df_out <- df %>%
  as_tibble() %>% # for easier viewing 
  mutate(day = format(as.Date(df$Date, format='%Y-%m-%d'), format='%m-%d')) %>%
  tidyr::pivot_longer(cols = -c(Date, day), 
                      names_to = "Stations", values_to = "MinT") %>%
  left_join(df_summarise_all %>% rename(mean_MinT = value), 
            by = c('day' = 'day', 'Stations' = 'variable')) %>%
  mutate(is_coldwave = MinT < ifelse(mean_MinT < 10, mean_MinT - 4, mean_MinT - 5))%>%
  mutate(is_severe_coldwave = MinT <= ifelse(mean_MinT < 10, mean_MinT - 5.5, mean_MinT - 6.5 ##values differing by 7 or more are is_severe_coldwave
                                              )) %>% 
  mutate(is_coldwave= ifelse(is_severe_coldwave == T, F, is_coldwave))  ##values labeled is_coldwave and is_severe_coldwave updated so that is_coldwave = F

【讨论】:

  • 根据定义,我认为我们应该舍入不带小数的偏差,当偏差为-6,正常最低温度> = 10°C时,应该是寒潮,而不是严重寒潮。但是您的代码的输出将其识别为严重的寒潮。你能看一下吗?
  • 我已经更新了代码来解决这个问题。
  • 仍然,输出中存在一些问题,例如应该如何对 6-7 之间的值进行分类?您当前的输出将值记录为冷波。我认为需要将出发值四舍五入到小数点零才能满足条件。
  • @BappaDas 我已将其更新为将出发值四舍五入为零。如果这不适用于特定案例,您能否告诉我该案例是什么(例如 minTmean_MinT)以及您希望它是什么?
  • 如果您将输出保存在 excel 中并计算 MinTmean_MinT 之间的差异并突出显示值
猜你喜欢
  • 1970-01-01
  • 2021-07-08
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
相关资源
最近更新 更多