Website: http://www.prism.oregonstate.edu/
Data description: http://www.prism.oregonstate.edu/documents/PRISM_datasets.pdf
PRISM provides gridded raster climate data for the continental USA. The data are temporal & spatial.
prism package: https://github.com/ropensci/prism
library(devtools) #needed to download prism from github
library(reshape2) ##melting dataframes
library(dplyr) #data wrangling
library(raster) ##working with raster data
library(sp) ##manipulationg spatial data
install_github(repo = "prism", username = "ropensci")
library(prism) ##prism data access
PRISM data is available for multiple temporal scales; annual, monthly, daily, and 30 year normals. Each has a unique function that requires the climatic variable you are interested in (type) and the resolution (4km or 800m).
Based on data from 1981-2010.
Pull 30 year precipitation normals for July at a 4km grid resolution
##to do
##get dailys for 2016 - ppt, tmean
options(prism.path = "/Volumes/collnell/CAT/data/prism/prism_temp")
get_prism_normals(type = 'tmean', resolution = '4km', mon = 12, keepZip = TRUE)
‘mon’ refers to the month of interest (July). Exchanging ‘mon’ for ‘annual = TRUE’ will download the normals for the whole year.
Look at the downloaded prism files in your directory
ls_prism_data(name=TRUE)
Normals data are labelled as PRISM_[climate variable abbreviation]_30yr_normal_[resolution]_[month]_bil
Convert raster data to point data
new_file<-1#this number corresponds to the row of the file of interest
RS <- prism_stack(ls_prism_data()[12,1]) ##raster file of data
proj4string(RS)<-CRS("+proj=longlat +ellps=WGS84 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs") ##assign projection info
To convert the raster data to a dataframe:
##convert raster to point data frame
df <- data.frame(rasterToPoints(RS))
m.df <- melt(df, c("x", "y"))
names(m.df)[1:2] <- c("lon", "lat") #rename columns
Raster data is easiest to plot when it is in a dataframe format. Raster format is easier for data manipulate (e.g. crop, change resolution & projection, extract values, aggregate data). I find it easiest to work with the raster data and extract what is needed, and reduce the size. Then, convert to the dataframe format to plot using ggplot2 and ggmap, which have the most flexibility in terms of aestetics.
Save files:
year<-'30yr_norm_12'
name<-paste0("/Volumes/collnell/CAT/data/prism/monthly_temp/USA/PRISM_tmean_", year,".csv")
write.csv(m.df, name)
writeRaster(RS, name)
Now we have a dataframe with longitude & latitude coordinates for each grid and the associated 30 year normal precipitation values.
head(m.df)
## X lon lat variable value
## 1 1 -95.12500 49.41667 PRISM_ppt_30yr_normal_4kmM2_07_bil 93.85
## 2 2 -95.16667 49.37500 PRISM_ppt_30yr_normal_4kmM2_07_bil 92.91
## 3 3 -95.12500 49.37500 PRISM_ppt_30yr_normal_4kmM2_07_bil 93.41
## 4 4 -95.08333 49.37500 PRISM_ppt_30yr_normal_4kmM2_07_bil 93.60
## 5 5 -95.04167 49.37500 PRISM_ppt_30yr_normal_4kmM2_07_bil 93.84
## 6 6 -95.00000 49.37500 PRISM_ppt_30yr_normal_4kmM2_07_bil 94.17
Annual, monthly, and daily data follow a similar format using one of the following functions for a designated time period:
get_prism_annual()
get_prism_monthly()
get_prism_dailys()
Data is available from 1891 through present however all data prior to 1981 are downloaded as a single file.
Download precipitation for the month of July from 1985 to 2016
get_prism_monthlys(type = 'ppt', years=1990:2016, mon = 7, keepZip = TRUE)
ls_prism_data(name=TRUE)
new_file<-c(1) ##change to corresponding file numbers
RS <- prism_stack(ls_prism_data()[new_file,1]) ##raster file
to_slice <- grep("_201607",RS[,1],value=T)##search through names
df <- data.frame(rasterToPoints(RS)) ##creates a dataframe of points
month.df <- melt(df, c("x", "y"))
names(month.df)[1:2] <- c("lon", "lat") #rename columns
PRISM datasets are large, easier to use once filtered to the region/time of interest.
Plot PRISM 30 year normals data
library(ggplot2) #plotting
library(ggmap) ##theme_nothing()
ggplot()+
geom_raster(data=m.df, aes(x=lon, y=lat, fill=value))+
theme_nothing(legend = TRUE)+
scale_fill_gradient2("Precipitation\n(inches)", low='red',mid='lightblue',high = 'darkslateblue', midpoint=100)+
labs(title="July Precipitation: 30-year normals")+coord_fixed(ratio=1.3)
SoCal is located approximately between 31 & 36 degrees latitude and -124 & -114 longitude.
minLat=31
maxLat=36
minLon=-124
maxLon=-114
month.df.socal<-month.df%>%filter(minLat < lat, lat < maxLat, minLon < lon, lon <maxLon)%>%
mutate(ppt = value)%>%
select(-value)
dim(month.df)
dim(month.df.socal)
month.df.socal$variable<-as.character(month.df.socal$variable)
july2016<-filter(month.df.socal, grepl(pattern = '2016', variable, fixed=TRUE))
ggplot()+
geom_raster(data=july2016, aes(x=lon, y=lat, fill=ppt))+
theme_nothing(legend = TRUE)+
scale_fill_gradient2("Precipitation\n(inches)", low='red',mid='lightblue',high = 'darkslateblue', midpoint=100)+
labs(title="July Precipitation: 2016")+coord_fixed(ratio=1.3)
Irvine is located at 33.6694649 latitude & -117.8231107
Los Angeles is located at 34.0522342 lat & -118.2436849 lon
San Diego is at 32.7153292 & -117.1572551
Palm Springs is at 33.8302961 & -116.5452921
Make a SpatialPointsDataFrame of cities and coordinates:
cities<-data.frame(cities =c('Irvine','LA', 'SD', 'Palm Springs'),
Lat = c(33.6694649, 34.0522342, 32.7153292, 33.8302961),
Long = c(-117.8231107, -118.2436849, -117.1572551, -116.5452921))
cities.spdf<-SpatialPointsDataFrame(coords=cities[,c('Long','Lat')],
data=cities, proj4string = CRS("+proj=longlat +ellps=WGS84 +no_defs"))
Extract climate for cities:
city.clim<-extract(RS, cities.spdf, fun=mean, na.rm=TRUE, sp=TRUE)
‘buffer =’ can be added to include a radius buffer around each point fomr which the data is pulled. Can use a vector- this example would be better if it included the appropriate radius of each city. Buffer is in the same units as the projection.
‘fun =’ allows you to set how the data should be summarized at each point because often it is larger than a single cell (using buffer & extracting from SpatialPolgyons) or may be on the border of multiple cells. You can write your own or use any of the standard mean, sum, min, max, etc.
‘sp = TRUE’ adds the extracted values to the dataframe of the Spatial* object.
See the ‘sp’ package for work with Spatial* class data.
- https://cran.r-project.org/doc/contrib/intro-spatial-rl.pdf
Image raster data in r
- http://neondataskills.org/R/Image-Raster-Data-In-R/
Using R as GIS
- https://pakillo.github.io/R-GIS-tutorial/