user2324097
user2324097

Reputation: 41

Stacking the climate data downloaded from PRISM in R

I downloaded the prism climate data for few years and I am hoping I could get some suggestions on how to stack these data for each individual year. So after the download and unzip, each month data is in different folder. I need to stack the monthly data for each year. I am quite new in R and I would really appreciate if I can get some suggestion on how to achieve this. The folder names are as follows: PRISM_ppt_stable_4kmM2_201312_bil PRISM_ppt_stable_4kmM2_201311_bil PRISM_ppt_stable_4kmM2_201310_bil and so on

Upvotes: 3

Views: 1766

Answers (4)

Robert Hijmans
Robert Hijmans

Reputation: 47091

Below is a variation on the script of @Amstell. It does not use separate RasterLayer objects and is thus easier to maintain, more versatile because s could have any number of layers. I suppose I would run list.files once, outside of the loop, and then use grep inside of the loop to get subsets.

    library(raster)
    setwd("./Prism Weather Data All/1895-2014_BIL/ppt")   
    years <- 1900:1900
    for (i in years) {
      filenames <- list.files(pattern=paste(".*_",i,".*\\.bil$", sep = ""))
      s <- stack(filenames)
      y <- data.frame(rasterToPoints(s))
      colnames(y) <- c("lon", "lat", month.abb)
      y$year <- i
      y$gridNumber <- cellFromXY(s, y[, 1:2])
      # write.csv( ) ?
    }

Also note that .../ is meaningless. Use ./ (or nothing) for the current directory, and ../ for the parent directory (and so on with ../../)

Upvotes: 3

Robert Hijmans
Robert Hijmans

Reputation: 47091

get the filenames with something like

 f <- list.files(pattern='.bil$', recursive=TRUE, full=TRUE)

Perhaps you need to order them. Then do

 s <- stack(f)

and then do whatever you want to do with the stack (which you do not specify). To get a matrix of values and cell centers you can do

 v <- rasterToPoints(s)

Upvotes: -1

Vedda
Vedda

Reputation: 7435

I have gotten quite a bit of help working with PRISM data from this site and am passing along some code to you to make this easier. The following code will pull out the information from the raster files and put it in a nice data.frame for each year you want.

Setup

It is very important to set a few things before this will run.

  1. Extract all *.bil and *.hdr files for all years you need into a specific directory
  2. setwd() is assigned to that directory with *.bil and *.hdr files
  3. path <- ".../" includes the path to export if you want for exporting years into a *.csv file--if you wish
  4. startingyear and endyear are assigned to whichever years you want to extract
  5. filenames <- list.files(path = ".../" is assigned to the directory with *.bil and *.hdr files. This should be the same as setwd()

Code

library(plyr)
library(dplyr)
library(raster)
library(rgdal)
library(tidyr)
library(reshape2)
library(data.table)

### Precipitation (ppt) ###

# !!!!!  Set to directory with *.hdr and *.bil only
setwd(".../Prism Weather Data All/1895-2014_BIL/ppt/")   

# Path to write out (if necessary)
path <- ".../Prism Weather Data All/csv/ppt/") 

# Set years to process
startingyear <- 1900       
endingyear <- 1900
total <- startingyear:endingyear

for (i in total) {
  year <- as.character(i)

  #  Make sure to set the correct path where *.hdr and *.bil are
  filenames <- list.files(path = ".../Prism Weather Data All/1895-2014_BIL/ppt/", 
                          pattern = paste(".*_", year, ".*\\.bil", sep = ""))

  # Assign raster file to object
  r1 = raster(filenames[1])
  r2 = raster(filenames[2])
  r3 = raster(filenames[3])
  r4 = raster(filenames[4])
  r5 = raster(filenames[5])
  r6 = raster(filenames[6])
  r7 = raster(filenames[7])
  r8 = raster(filenames[8])
  r9 = raster(filenames[9])
  r10 = raster(filenames[10])
  r11 = raster(filenames[11])
  r12 = raster(filenames[12])

  # Assign values from raster file to month object
  jan <- as.data.frame(r1, na.rm = TRUE)
  feb <- as.data.frame(r2, na.rm = TRUE)
  mar <- as.data.frame(r3, na.rm = TRUE)
  apr <- as.data.frame(r4, na.rm = TRUE)
  may <- as.data.frame(r5, na.rm = TRUE)
  jun <- as.data.frame(r6, na.rm = TRUE)
  jul <- as.data.frame(r7, na.rm = TRUE)
  aug <- as.data.frame(r8, na.rm = TRUE)
  sep <- as.data.frame(r9, na.rm = TRUE)
  oct <- as.data.frame(r10, na.rm = TRUE)
  nov <- as.data.frame(r11, na.rm = TRUE)
  dec <- as.data.frame(r12, na.rm = TRUE)

  # Bind all gridnumbers with monthly data to object
  jan <- cbind(gridNumber = rownames(jan), jan, stringsAsFactors = FALSE)
  feb <- cbind(gridNumber = rownames(feb), feb, stringsAsFactors = FALSE)
  mar <- cbind(gridNumber = rownames(mar), mar, stringsAsFactors = FALSE)
  apr <- cbind(gridNumber = rownames(apr), apr, stringsAsFactors = FALSE)
  may <- cbind(gridNumber = rownames(may), may, stringsAsFactors = FALSE)
  jun <- cbind(gridNumber = rownames(jun), jun, stringsAsFactors = FALSE)
  jul <- cbind(gridNumber = rownames(jul), jul, stringsAsFactors = FALSE)
  aug <- cbind(gridNumber = rownames(aug), aug, stringsAsFactors = FALSE)
  sep <- cbind(gridNumber = rownames(sep), sep, stringsAsFactors = FALSE)
  oct <- cbind(gridNumber = rownames(oct), oct, stringsAsFactors = FALSE)
  nov <- cbind(gridNumber = rownames(nov), nov, stringsAsFactors = FALSE)
  dec <- cbind(gridNumber = rownames(dec), dec, stringsAsFactors = FALSE)

  # Merge Monthly data
  month_list <- lapply(list(jan,feb,mar, apr, may, jun, jul, aug, sep, oct, nov, dec),setDT)
  for(j in seq_along(month_list)){
  set(month_list[[j]],j="ID",value = names(month_list[[j]])[2])
  setnames(month_list[[j]],  names(month_list[[j]])[2], "value")
  }

  # Faster processing of aggregated data
  long_data <- rbindlist(month_list)
  wide <- dcast.data.table(long_data, gridNumber~ID, value = 'value')
  wide$year <- year
  colnames(wide) <- c("gridNumber", "jan","feb","mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec", "year")
}

Results

enter image description here

Upvotes: 1

Reign
Reign

Reputation: 11

What is the format of the files the data are in? Is it csv or some text? If it is csv You can use read.csv function in R, it will create a neat data.frame object for You.

You can create some iterator for each year to read data from each folder, for example:

year = 2010:2014
months = 1:12
folder_names = sapply(year, function(y) { sapply(month, function(m){ 
                    paste(
                        paste(
                              paste("PRISM_ppt_stable_4kmM2_", y, sep=""), 
                               m, sep=""),
                          "_bil", sep="") }) })

and this way, You have all Your directory names generated.

Now You can perform reading from them, but for that we need to know files You keep data in.

Upvotes: 0

Related Questions