2

I want to determine the length of the snow season in the following data frame:

DATE    SNOW
1998-11-01  0
1998-11-02  0
1998-11-03  0.9
1998-11-04  1
1998-11-05  0
1998-11-06  1
1998-11-07  0.6
1998-11-08  1
1998-11-09  2
1998-11-10  2
1998-11-11  2.5
1998-11-12  3
1998-11-13  6.5
1999-01-01  15
1999-01-02  15
1999-01-03  19
1999-01-04  18
1999-01-05  17
1999-01-06  17
1999-01-07  17
1999-01-08  17
1999-01-09  16
1999-03-01  6
1999-03-02  5
1999-03-03  5
1999-03-04  5
1999-03-05  5
1999-03-06  2
1999-03-07  2
1999-03-08  1.6
1999-03-09  1.2
1999-03-10  1
1999-03-11  0.6
1999-03-12  0
1999-03-13  1

Snow season is defined by a snow depth (SNOW) of more than 1 cm for at least 10 consecutive days (so if there is snow one day in November but after it melts and depth is < 1 cm we consider the season not started).

My idea would be to determine:

1) the date of snowpack establishement (in my example 1998-11-08)

2) the date of "disappearing" (here 1999-03-11)

3) calculate the length of the period (nb of days between 1998-11-05 and 1999-03-11)

For the 3rd step I can easily get the number between 2 dates using this method.

But how to define the dates with conditions?

Community
  • 1
  • 1
user2165907
  • 1,401
  • 3
  • 13
  • 28

1 Answers1

0

This is one way:

# copy data from clipboard
d <- read.table(text=readClipboard(), header=TRUE)
# coerce DATE to Date type, add event grouping variable that numbers the groups
# sequentially and has NA for values not in events.
d <- transform(d, DATE=as.Date(DATE),
                  event=with(rle(d$SNOW >= 1), rep(replace(ave(values, values, FUN=seq), !values, NA), lengths)))
# aggregate event lengths in days
event.days <- aggregate(DATE ~ event, data=d, function(x) as.numeric(max(x) - min(x), units='days'))
# get those events greater than 10 days
subset(event.days, DATE > 10)
#   event DATE
# 3     3  122

You can also use the event grouping variable to find the start dates:

starts <- aggregate(DATE ~ event, data=d, FUN=head, 1)
# 1     1 1998-11-04
# 2     2 1998-11-06
# 3     3 1998-11-08
# 4     4 1999-03-13

And then merge this with event.days:

merge(event.days, starts, by='event')
#   event DATE.x     DATE.y
# 1     1      0 1998-11-04
# 2     2      0 1998-11-06
# 3     3    122 1998-11-08
# 4     4      0 1999-03-13
Matthew Plourde
  • 43,932
  • 7
  • 96
  • 113