0
votes

I'm working with some meteorology data in R, and conceptually, I'm trying to find out how much a certain day is above/below average. To do this, I want to separate by day of year, find the average for all DOY (e.g. what is the average January 1 Temperature?), and then compare every date (e.g was January 1, 2014 anomalously warm, by how much?)

I can find a 'mean' table for every day of the year using aggregate:

head(data)
          x       date
1  5.072241 1970-01-01
2  6.517069 1970-01-02
3  4.413654 1970-01-03
4 11.129351 1970-01-04
5  9.331630 1970-01-05

library(lubridate)
temp = aggregate(data$x, list(yday(data$date)), mean)

but I'm stuck then how to use the aggregated table to compare with my original data.frame, to see how x at 1970 Jan 1 relates to average Jan 1 x.

3

3 Answers

3
votes

We can remove the 'year' part with sub ('Monthday'). Use ave if a Mean variable needs to be created grouped by 'Monthday'.

data$Monthday <- sub('\\d+-', '', data$date)
data$Mean <- with(data, ave(x, Monthday))

Then, we can compare with 'x' variable, for example

data$rel_temp <- with(data, x/Mean)
3
votes

You should use dplyr as well.

library(dplyr); library(lubridate)

data %>% mutate(year_day = paste0(month(date), "_",mday(date))) %>% 
  group_by(year_day) %>% mutate(relev_temp = x/mean(x)) %>% ungroup

The logic is the following: Create a new variable year_day which is just the month and day of every date mutate(year_day =...

Then take the temperature x and divide with the average temp of that year_day, group_by(year_day) %>% mutate(relev_temp = x/mean(x))

0
votes

Thanks for the feedback. @akrun's answer works well for me.

As an alternative, I also hacked this together, which produces the same output as @akrun's answer (and is 1/10th of a second slower for 40 yrs of daily data):

    averages = aggregate(x, list(DOY = yday(date)), mean)
    temp = merge(data.frame(x,date, DOY = yday(date)), averages, by = 'DOY')  
    head(temp[order(temp$date),])
    DOY   x.x       date       x.y
1     1 -12.0 1970-01-01 -8.306667
70    2 -14.2 1970-01-02 -8.695556
113   3 -16.7 1970-01-03 -8.060000
157   4 -13.6 1970-01-04 -8.233333
200   5 -19.2 1970-01-05 -8.633333
243   6 -15.0 1970-01-06 -8.922222