1

If I have a dataframe that looks something like this:

  df <- data.frame(
  NestID = c(rep("LB1_2014", 9), rep("LB2_2014", 2)),
  Datetime = seq(from = ymd_hms("2014-04-02 05:00:00"), to = ymd_hms("2014-04-02 15:00:00"), by = "1 hour"),
  Temp = c(29.083, 29.200, 28.536, 28.221, 27.934, 28.417, 28.942, 29.323, 29.42, 28.93, 28.28),
  Flooded = c(rep(FALSE, 2), TRUE, rep(FALSE, 8)))

   > df
     NestID            Datetime   Temp Flooded
1  LB1_2014 2014-04-02 05:00:00 29.083   FALSE
2  LB1_2014 2014-04-02 06:00:00 29.200   FALSE
3  LB1_2014 2014-04-02 07:00:00 28.536    TRUE
4  LB1_2014 2014-04-02 08:00:00 28.221   FALSE
5  LB1_2014 2014-04-02 09:00:00 27.934   FALSE
6  LB1_2014 2014-04-02 10:00:00 28.417   FALSE
7  LB1_2014 2014-04-02 11:00:00 28.942   FALSE
8  LB1_2014 2014-04-02 12:00:00 29.323   FALSE
9  LB1_2014 2014-04-02 13:00:00 29.420   FALSE
10 LB2_2014 2014-04-02 14:00:00 28.930   FALSE
11 LB2_2014 2014-04-02 15:00:00 28.280   FALSE

I want to find the magnitude of the first temperature drop for each NestID.

So after a Flooded == TRUE,

the Temp from the row above is TempBefore

and then find the minimum Temp reached before the Temp rises to TempBefore again.

(Flooded == TRUE is simply acknowledging a minimum value of temperature drop.)

Magnitude = TempBefore - MinTemp

I have the beginning of the code and (I think!) the end, I am hoping it is just a line or two that are missing.

The output I am looking for is a single line for each NestID and Magnitude. NA for magnitude if Flooded != TRUE.

For this example data the output I would want is:

TempBefore = 29.200, MinTemp = 27.934

Hence

     NestID  Magnitude
1  LB1_2014      1.266
2  LB2_2014         NA

(There may be multiple Flooded events, but for simplicity I am only looking for the magnitude of the first Flooded == TRUE event. )

FloodingMagnitude = group_by (df, NestID) %>% 
    mutate(TempBefore = if_else(Flooded == TRUE, 
                        lag(Temp, default = first(Temp)), as.double(NA))) %>%

    # line of code I need to work:
    mutate(MinTemp = min(Temp) before it reaches TempBefore again) %>% 
    
    mutate(Magnitude = TempBefore - MinTemp) %>% 
    distinct(NestID, Magnitude)
bex
  • 23
  • 4
  • @RonakShah Thank you! I have updated my question. I hope that clarifies it. – bex Jul 28 '21 at 13:43
  • Could you add the final dataframe for your example data? – coffeinjunky Jul 28 '21 at 14:04
  • @RonakShah I have added the BeforeTemp & MinTemp above. Sorry! – bex Jul 29 '21 at 10:35
  • I have now updated the text & data. I think I confused people before. Flooded == TRUE is triggered by a minimum value Temp drop. It will not remain TRUE for the extent of the event. – bex Jul 31 '21 at 10:48

1 Answers1

1

Maybe this will help -

library(dplyr)

df %>%
  filter(Flooded | lead(Flooded)) %>%
  group_by(NestID, Flooded = data.table::rleid(Flooded)) %>%
  slice(n()) %>%
  group_by(NestID) %>%
  summarise(Magnitude = Temp - lead(Temp), .groups = 'drop')

#  NestID   Magnitude
#  <chr>        <dbl>
#1 LB1_2014      1.56
#2 LB1_2014     NA   
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Thank you, but no. In this instance, the minimum Temp happens to be the next value, but it may be 6 hours or 24 hours later in my actual dataset. Unless I am misunderstanding your code. I am new at this! – bex Jul 29 '21 at 17:16