Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
292 views
in Technique[技术] by (71.8m points)

r - How to calculate a condition using dplyr?

I want to calculate the following condition using dplyr

a) When the normal minimum temperature is equal to 10°C or more.

Cold Wave: Departure from normal is -5°C to -6°C.

Severe Cold Wave: Departure from normal is -7°C or less

b) When the normal minimum temperature is less than 10°C.

Cold Wave: Departure from normal is -4°C to -5°C.

Severe Cold Wave: Departure from normal is -6°C or less.

I am using the following code

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))

I could not implement the condition -5°C to -6°C and -4°C to -5°C. How can this be achieved using dplyr?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As I understand it, you want a column that checks if the temperature deviates by 5 - 6 degrees (if the temp is greater than 10) and another column to check if it is differs by 7 degrees or more.

The current code you are using seems to identify the coldwave values correctly, although is including the severe_coldwave values as well.

You could add another check for the severe weather, similar to what is already coded, and set any is_coldwave values to FALSE if the weather is severe.

This will set values that deviate from 5-6.5 degrees to is_coldwave and more than 6.5 to 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...