I have 10 year NDVI data i.e. two values per month. I would like to average values within a season e.g Season A (January, February and March) per year and plot a graph. y axis=average ndvi value, x axis=year

I have already given a time vector as an attribute to the stack using teh code below


I've also calculated mean NDVI for each raster and converted the array to a data frame using the code below

r1 <- as.data.frame(cellStats(r,mean, na.rm=TRUE))

2 Answers 2


Addressing your exact output and expanding on the code you provided, you could query by date (the advantage of Posix) and index the rasters in a stack object. The use of "which" returns the raster stack/brick index meeting the query criteria. The use of "apply" is to sum rows, which represent pixels, to derive a seasonal sum to average. For large rasters that are not in memory you may need to use getValues.

r <- raster(ncol=10, nrow=10)
  r[] <- runif(ncell(r))
  s <- stack(r,r,r,r,r,r,r,r,r,r)
  s <- stack(lapply(1:10, function(x) setValues(r, runif(ncell(r)))))
  s <- setZ(s, as.Date('2000-1-1') + 0:9)

mean( apply(s[which(getZ(s) < "2000-01-04")], MARGIN=1, FUN=sum) )
mean( apply(s[which(getZ(s) >= "2000-01-04")], MARGIN=1, FUN=sum) )

# data.frame output
( s.mean <- data.frame(   
  s1.mean = mean( apply(s[which( getZ(s) <  "2000-01-04")], MARGIN=2, FUN=sum) ),
  s2.mean = mean( apply(s[which( getZ(s) <=  "2000-01-04")], MARGIN=2, FUN=sum) ) ) )

I will say that this is not a valid way to summarize the data and you are collapsing a considerable amount of variation in to a single number but, I will leave it to you to figure out. However, please talk with somebody that is statistically savvy about the effect of skewed distributions on means and better ways to summarize spatially variable data.

  • these are NDVI values in a very small area.
    – jmutua
    Jul 1, 2016 at 10:54

I found a solution using the mutate function in dplyr package. Make sure you have a data frame with a column defining the months e.g m1, m2 etc

df_Seasons <- df %>%
mutate(season =
ifelse(month %in% c(m1, m2, m3), "Season 1",
ifelse(month %in% c(m4, m5, m6), "Season 2",
ifelse(month %in% c(m7, m8, m9), "Season 3", "Error"))))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.