Estimation of probability of site occupancy and abundance for eastern whip-poor-will (Antrostomus vociferus) in the U.S. Fish and Wildlife (USFWS) Northeast Region to support the management planning and guidance developed by the At-Risk Pine Barrens Working group.
The purpose of this modeling effort is to identify key areas of high conservation importance for eastern whip-poor-will and where these areas are in relation to the imperriled frosted elfin (Callophrys irus)
Using citizen-science based eBird data (https://ebird.org/home) we estimated the probability of site occupancy and relative abundance for the eastern whip-poor-will throughout the USFWS Northeast Region. These data were downloaded from eBird checklists where observers detected whip-poor-wills during the breeding season in June, July, and August annualy from 2016-2021. These data were then sampled to generate a spatially-balanced data set, and analyzed using hierarchical N-mixture models using the ‘unmarked’ package in program R (Core Team R 2022). Combined with Landfire data consisiting of 12 unique ecosystem types and elevation, we then modeled probability of site occupancy and abundance while accounting for imperfect detection. Finally, we predicted (mean and SE) the spatially-explicit probability of whip-poor-will occupancy and abundance across a 5-km^2 resolution surface of the Northeast region to aid in identifying key areas where whip-poor-will occur (and do not occur), to help inform next steps for the Pine Barrens Habitat At-risk working group’s action plan.
#clear environment
rm(list=ls())
#load packages
suppressMessages({
library(knitr)
library(readxl)
library(unmarked)
library(ggplot2)
library(ggrepel)
library(ggmap)
library(lubridate)
library(data.table)
library(reshape2)
library(plyr)
library(kableExtra)
library(pander)
library(raster)
library(pals)
library(rgdal)
library(gdalUtils)
library(sp)
library(lattice)
library(dplyr)
library(rgeos)
library(exactextractr)
library(purrr)
library(tidyr)
library(dismo)
library(ggsn)
library(MuMIn)
library(rebird)
library(sf)
library(dggridR)
# resolve namespace conflicts
select <- dplyr::select
map <- purrr::map
projection <- raster::projection
#set working directory
opts_knit$set(root.dir = "/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/")
#setwd("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/")
#register Google Maps API key
register_google(key="AIzaSyBLb0jdTnIwfWzduauW5sjfxE91hnqRvfE")
#load functions
source("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Source/makePOccu_umf.R")
source("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Source/makePOccu_umf_with_covs.R")
source("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Source/makePCount_umf.R")
source("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Source/makePCount_umf_with_covs.R")
source("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Source/AICcmodavg.gof.test_source.R")
source("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Source/xyToLatLong.R")
})
#define API key from https://ebird.org/api/keygen
myKey<-"u9drtus3ammg"
#example query for historic data
test.data<-ebirdhistorical(loc ="US-ME",date='2019-06-15', fieldSet='full', key=myKey)
#iterate through dates in June to get detection data
#first create list of dates (last 5 years)
dates2017<-seq.Date(from=as.Date("2017-06-01"), to=as.Date("2017-09-1"), by=1)
dates2018<-seq.Date(from=as.Date("2018-06-01"), to=as.Date("2018-09-1"), by=1)
dates2019<-seq.Date(from=as.Date("2019-06-01"), to=as.Date("2019-09-1"), by=1)
dates2020<-seq.Date(from=as.Date("2020-06-01"), to=as.Date("2020-09-1"), by=1)
dates2021<-seq.Date(from=as.Date("2021-06-01"), to=as.Date("2021-09-1"), by=1)
#combine into a single list
datesList<-as.character(c(dates2017, dates2018, dates2019, dates2020, dates2021))
#get list of locations
locList<-c("US-CT","US-DE","US-ME","US-MD","US-MA","US-NH","US-NJ","US-NY","US-PA","US-RI","US-VT","US-VA","US-WV")
#empty list to capture data
save.data<-list()
#for loop
for(i in 1:length(locList)){
#new location
new.loc<-locList[i]
print(new.loc)
#empty list to save date data
date.data<-list()
for(j in 1:length(datesList)){
#new date
new.date<-datesList[j]
print(new.date)
#get new.data
new.data<-ebirdhistorical(loc = new.loc ,date=new.date, fieldSet='full', key=myKey)
date.data<-rbind(date.data, new.data)
}
#now row bind location data
save.data<-rbind(save.data,date.data)
}
#save data
write.csv(save.data, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/eBird_USFWS_LR5_data.csv",row.names = FALSE)
#get state polygons
stateMap <- raster::getData('GADM', country='USA', level=2)
#list of states
statesList<-c("Connecticut","Delaware","Maine","Maryland","Massachusetts","New Hampshire","New Jersey","New York","Pennsylvania","Rhode Island","Vermont","Virginia","West Virginia")
#subset to only include desired states
states.sub<-stateMap[stateMap@data$NAME_1 %in% statesList,]
states.poly<-fortify(states.sub, region="NAME_1")
states.poly <- states.poly[order(states.poly$order),]
states.poly$id<-as.factor(states.poly$id)
#read in save.data
save.data<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/eBird_USFWS_LR5_data.csv",header=TRUE)
#remove unverified checklists
save.data.sub<-subset(save.data, obsReviewed==TRUE)
#keep all checklists
save.data.sub<-save.data
# replace any non-whip-poor-will data with 0s
save.data.sub$howMany<-ifelse(save.data.sub$speciesCode=="easwpw1",save.data.sub$howMany,0)
#make column for WPWI_Present a factor
save.data.sub$WPWI_Present<-ifelse(save.data.sub$howMany>0,"WPWI","NO_WPWI")
#levels(save.data.simp.2$WPWI_Present)
#filter checklists where detections occur within CONUS (remove any lists from marine/offshore)
#get only points that intersect state polygons
myPoints<-st_as_sf(save.data.sub, coords = c("lng", "lat"), crs = 4326)
myPolys<-st_as_sf(states.sub)
#plot(myPolys)
#get points intersecting polygons
pts_in<-st_intersects(myPoints, myPolys)
#length(pts_in)
#grab all rows for points that intersect the state polygons
pts_in.df<-list()
for(i in 1:length(pts_in)){
#print(i)
new.value<-ifelse(length(unlist(pts_in[i]))==0,0,unlist(pts_in[i]))
new.data<-data.frame("row.id"= i ,"num_pts"=new.value)
pts_in.df<-rbind(pts_in.df, new.data)
}
#subset to remove any rows with num_pts==0
pts_in.df.sub<-subset(pts_in.df, num_pts!=0)
#make row.id a character
pts_in.df.sub$row.id<-as.character(pts_in.df.sub$row.id)
#merge with save.data.simp
#add row names as row.id field in save.data.simp
save.data.sub$row.id<-seq(1, nrow(save.data.sub), by=1)
save.data.merge<-merge(save.data.sub, pts_in.df.sub, by="row.id",all.y=TRUE)
#remove NAs
save.data.merge<-na.omit(save.data.merge)
#export save.data.merge
write.csv(save.data.merge, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/eBird_USFWS_LR5_data_filter.csv",row.names=FALSE)
save.data.merge<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/eBird_USFWS_LR5_data_filter.csv")
#define map projection
map_proj <- "+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
#get bounding box coords from eBird data
x.min=min(save.data.merge$lng, na.rm=TRUE)-0.4
x.max=max(save.data.merge$lng, na.rm=TRUE)+0.4
y.min=min(save.data.merge$lat, na.rm=TRUE)-0.3
y.max=max(save.data.merge$lat, na.rm=TRUE)+0.3
#compile bounding box corner coordinates
ebird.bbox = c(left = x.min, bottom = y.min, right = x.max, top = y.max)
#define map area and type
basemap <- get_map(location =ebird.bbox, maptype="toner-lite", zoom=8)
## maptype = "toner-lite" is only available with source = "stamen".
## resetting to source = "stamen"...
## Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under ODbL.
## 156 tiles needed, this may take a while (try a smaller zoom).
#ggmap(basemap)
# #get map extent
mapExtent<-attr(basemap, "bb")
save.data.merge<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/eBird_USFWS_LR5_data_filter.csv")
#add Year and Month and Week columns
save.data.merge$Year<-year(as.Date(save.data.merge$obsDt, format="%Y-%m-%d"))
save.data.merge$Month<-month(as.Date(save.data.merge$obsDt, format="%Y-%m-%d"))
save.data.merge$Week<-week(as.Date(save.data.merge$obsDt, format="%Y-%m-%d"))
#iterate over years and months to get repeated 3 repeated visits per year
yearList<-sort(unique(save.data.merge$Year))
monthList<-sort(unique(save.data.merge$Month))
#subset out WPWI detections
wpwi.data<-subset(save.data.merge, howMany>0)
non.wpwi.data<-subset(save.data.merge, howMany<1)
#empty list to save spatially-sampled data (non-WPWI)
save.spatial.data<-list()
for(i in 1:length(yearList)){
print(yearList[i])
count.data.year<-subset(non.wpwi.data, Year==yearList[i])
save.spatial.month<-list()
for(j in 1:length(monthList)){
print(monthList[j])
count.data.month<-subset(count.data.year, Month==monthList[j])
#get weekList
weekList<-unique(count.data.month$Week)
save.spatial.week<-list()
for(z in 1:length(weekList)){
count.data.week<-subset(count.data.month, Week==weekList[z])
# generate hexagonal grid with ~ 35 km betweeen cells
dggs <- dgconstruct(spacing = 50)
# get hexagonal cell id for each site
occ_wide_cell <- count.data.week %>%
mutate(cell = dgGEO_to_SEQNUM(dggs, lng, lat)$seqnum)
# sample one site per grid cell
occ_ss <- occ_wide_cell %>%
group_by(cell) %>%
sample_n(size = 1) %>%
ungroup() %>%
select(-cell)
# calculate the percent decrease in the number of sites
#1 - nrow(occ_ss) / nrow(occ_wide)
#add Hexagon back in
occ_hex<-merge(occ_ss, occ_wide_cell[,c("row.id","cell")],by="row.id",all.x=TRUE)
#compile
save.spatial.week<-rbind(save.spatial.week, occ_hex)
}
#compile
save.spatial.month<-rbind(save.spatial.month, save.spatial.week)
}
#compile
save.spatial.data<-rbind(save.spatial.data, save.spatial.month)
}
# get hexagonal cell id for wpwi
wpwi.cell <- wpwi.data %>%
mutate(cell = dgGEO_to_SEQNUM(dggs, lng, lat)$seqnum)
#add wpwi.cell to sampled data
save.spatial.data.all<-rbind(save.spatial.data,wpwi.cell)
#count how many detections and non-detections in full data and sampled data
sampledDetections<-subset(save.spatial.data.all, howMany>0)
nrow(sampledDetections)
sampledDetectionsUnique<-unique(sampledDetections)
fullDetections<-subset(save.data.merge, howMany>0)
nrow(fullDetections)
#define Points column
save.data.merge$Points<-paste("All (n = ",length(unique(save.data.merge$obsId)), ")",sep="")
save.spatial.data.all$Points<-paste("Sampled (n = ", length(unique(save.spatial.data.all$obsId)), ")", sep="")
#remove cell column to produce comparison figure
save.spatial.data.1<-save.spatial.data.all
save.spatial.data.1$cell<-NULL
occ_comb<-rbind(save.data.merge, save.spatial.data.1)
occ_comb$Points<-as.factor(occ_comb$Points)
plotColors<-c("gray20","blue")
subSamplePlot<-ggmap(basemap, darken=c(0.7,"white"))+
geom_point(data=occ_comb, aes(x=lng,y=lat,color=Points),size=0.2,alpha=0.7, shape=16, inherit.aes = FALSE)+
geom_sf(data = hexagons,inherit.aes = FALSE,color="black",alpha=0.5,size=0.3)+
theme(panel.border=element_rect(color="black",fill="transparent"), panel.background = element_rect(fill="white"))+
scale_color_manual(values=plotColors)+
labs(x="Longitude",y="Latitude")+
guides(alpha="none")
subSampleFacet<-subSamplePlot+facet_wrap(.~Points)
subSampleFacet
ggsave(subSampleFacet, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_1_WPWI_spatial_sampling_eBird.png",
width=9, height=6, dpi=600)
#Load the saved image of raster veg layer
include_graphics("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_1_WPWI_spatial_sampling_eBird.png")
###############################################################################
#make a map of presence absence data
#plot sampling locations over study area basemap
studyAreaMap<-ggmap(basemap)+
geom_map(data=states.poly, map=states.poly, aes(y=lat, x=long, map_id=id),color="black",fill="gray90",alpha=0.4, inherit.aes = FALSE)+
geom_point(data=save.spatial.data.all, aes(x=lng, y=lat, color=WPWI_Present), shape=16,size=1)+
scale_color_manual(values=c(alpha("gray40",0.3),"red"), name="Detected")+
labs(x="Longitude",y="Latitude")+
theme(axis.text=element_text(size=12),
axis.title=element_text(size=14),
panel.border=element_rect(fill="transparent", color="black"),
legend.position = "right")+
ggtitle("Map of detections and non-detections")+
#geom_text_repel(check_overlap = FALSE, size=3, nudge.y=-10, nudge.x=-10,aes(x=Longitude, y=Latitude,color=PatchID, label=PatchID),data=PatchID_labels)+
#guides(fill = guide_legend(title = "National Wildlife Refuge", label = FALSE))+
ggsn::scalebar(x.min=mapExtent$ll.lon, x.max=mapExtent$ur.lon, y.min=mapExtent$ll.lat, y.max=mapExtent$ur.lat,transform=TRUE, dist_unit="km",dist=200, st.dist=0.04, height = 0.015, anchor=c(x=-68,y=38.6), border.size=0.5,st.size=3)
studyAreaMap
ggsave(studyAreaMap, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_2_WPWI_presence_absence_eBird.png",width=9, height=9, dpi=600)
#Load the saved image of raster veg layer
include_graphics("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_2_WPWI_presence_absence_eBird.png")
#add hexagonal cell id for each site
save.spatial.data_hex <- save.spatial.data.all
names(save.spatial.data_hex)[names(save.spatial.data_hex)=="cell"]<-"Hexagon"
#Set up dataframe with repeated visits
#create Date column
save.spatial.data_hex$Date<-as.Date(save.spatial.data_hex$obsDt, format = "%Y-%m-%d")
#add Time column
save.spatial.data_hex$obsDt<-as.POSIXct(save.spatial.data_hex$obsDt, format = "%Y-%m-%d %H:%M")
save.spatial.data_hex$Time<-format(save.spatial.data_hex$obsDt, format = "%H:%M")
#now aggregate over weeks and get max counts at each hexagon
data.agg<-aggregate(howMany~Year+Month+Time+Hexagon+lat+lng, FUN=max, data=save.spatial.data_hex)
#make Hexagon a factor
data.agg$Hexagon<-as.factor(as.character(data.agg$Hexagon))
#cast data to put Weeks in columns
data.agg.cast<-reshape2::dcast(data.agg, Hexagon~Month,value.var="howMany",fun.aggregate = max )
#subset to get checklists with at least 3 repeated visits
data.agg.cast.sub<-subset(data.agg.cast, c(`6`!="-Inf" & `7` !="-Inf" & `8`!="-Inf" ))
#add in Hexagon Latitude and Longitudes
#cast data to put Weeks in columns
hex.lat.cast<-stats::aggregate(lat~Hexagon, FUN=mean, data=data.agg)
hex.lng.cast<-stats::aggregate(lng~Hexagon, FUN=mean, data=data.agg)
#combine
hex.coords<-merge(hex.lat.cast, hex.lng.cast, by="Hexagon",all.x=TRUE)
#merge with count data
data.agg.merge<-merge(data.agg.cast.sub, hex.coords, by="Hexagon",all.x=TRUE)
#save data
write.csv(data.agg.merge, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/WPWI_data_5years_wide.csv",row.names=FALSE)
count.data<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/WPWI_data_5years_wide.csv")
#rename columns
names(count.data)<-c("Hexagon","Jun","Jul","Aug","Latitude","Longitude")
#add visit columns
count.data$Visit_1<-"Visit_1"
count.data$Visit_2<-"Visit_2"
count.data$Visit_3<-"Visit_3"
#convert data to an unmarked frame
#define counts
y=data.frame(y.1=count.data$Jun, y.2=count.data$Jul, y.3=count.data$Aug)
#step to convert all y values > 1 to 1
y$y.1<-ifelse(y$y.1 > 1, 1, y$y.1)
y$y.2<-ifelse(y$y.2 > 1, 1, y$y.2)
y$y.3<-ifelse(y$y.3 > 1, 1, y$y.3)
#define site covariates - FOR MULTIPLE YEARS
site.covs<- data.frame(PointID=as.factor(count.data$Hexagon),
Latitude=as.numeric(count.data$Latitude),
Longitude=as.numeric(count.data$Longitude))
#define observation covariates
obs.covs<-list(Visit=count.data[,c("Visit_1","Visit_2","Visit_3")])
#set up unmarked FRAME for PCount
occu.umf<-unmarkedFrameOccu(y=y,siteCovs = site.covs,obsCovs= obs.covs)
#fit example model to test
occu.mod<-NULL
occu.mod<-occu(~Visit ~1, data=occu.umf)
suppressMessages({
#run GOF test
mod.gof<- try(mb.gof.test(occu.mod, nsim = 10, plot.hist = FALSE, report = NULL, parallel = FALSE))
#get c-hat (goodness of fit test)
mod.c.hat<-mod.gof$c.hat.est
#get predicted estimates
occu.mod.predict<-unique(predict(occu.mod, type="state",appendData=TRUE))
})
#remove columns
occu.mod.predict<-unique(occu.mod.predict[,c("Predicted","SE")])
#remove row.names
row.names(occu.mod.predict)<-NULL
#add GOF statisitc
occu.mod.predict$GOF_c_hat<- mod.c.hat
colnames(occu.mod.predict)<-c("Mean p(Occupancy)","SE p(Occupancy)","GOF (c-hat)")
panderOptions('table.alignment.default', function(df) ifelse(sapply(df, is.numeric), 'right', 'left'))
panderOptions("table.split.table", Inf)
pander(occu.mod.predict)
Mean p(Occupancy) | SE p(Occupancy) | GOF (c-hat) |
---|---|---|
0.4757 | 0.03312 | 1.735 |
#define counts
y=data.frame(y.1=count.data$Jun, y.2=count.data$Jul, y.3=count.data$Aug)
abun.umf<-unmarkedFramePCount(y=y,
siteCovs = site.covs,
obsCovs= obs.covs)
#fit example model to test
abun.mod<-NULL
abun.mod<-pcount(~Visit ~1, data=abun.umf)
suppressMessages({
#run GOF test
mod.gof<- Nmix.gof.test(abun.mod, nsim = 20, plot.hist = FALSE,report = NULL, parallel = FALSE)
#get c-hat
mod.c.hat<-mod.gof$c.hat.est
#set to NA for now, as it prints message otherwise (need to suppress somehow)
#mod.c.hat<-NA
#get predicted estimates
abun.mod.predict<-unique(predict(abun.mod, type="state",appendData=TRUE))
})
#remove columns
abun.mod.predict<-unique(abun.mod.predict[,c("Predicted","SE")])
#remove row.names
row.names(abun.mod.predict)<-NULL
#add c-hat goodness of fit
abun.mod.predict$GOF_c_hat<-mod.c.hat
colnames(abun.mod.predict)<-c("Mean abundance\n(birds per sampling location)","SE abundance","GOF (c-hat)")
panderOptions('table.alignment.default', function(df) ifelse(sapply(df, is.numeric), 'right', 'left'))
panderOptions("table.split.table", Inf)
pander(abun.mod.predict)
Mean abundance (birds per sampling location) | SE abundance | GOF (c-hat) |
---|---|---|
2.174 | 0.2008 | 3.286 |
#load vegetation raster layer
veg.raster<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LF2016_EVT_200_CONUS/Tif/LC16_EVT_200.tif")
#get extent of basemap
basemapExt<-attr(basemap, "bb")
#convert map extent from lat/long to UTM
basemapExt.df<-data.frame("long"=c(basemapExt$ll.lon, basemapExt$ur.lon),"lat"=c(basemapExt$ll.lat, basemapExt$ur.lat))
basemap_extent_sp<-SpatialPoints(cbind(basemapExt.df$long, basemapExt.df$lat), proj4string=CRS("+proj=longlat"))
#project to AEA
basemap_extent_AEA <- spTransform(basemap_extent_sp, projection(veg.raster))
#crop veg raster
veg.raster_crop<-crop(veg.raster, extent(basemap_extent_AEA))
#bring in States
#plot(states.sub)
#plot(veg.raster_crop)
#plot(sharp_patches_sub, col="blue")
#projection(sharp_patches_sub)
#reproject sharp_patches_sub
states_proj<-spTransform(states.sub, CRS(projection(veg.raster_crop)))
#dissolve states into one polygon, but first fix self-intersection regions with gBuffer, width=0
states_proj_valid<-gBuffer(states_proj, byid=TRUE, width=0)
#dissolve using sp::aggregate
states_proj_dissolve<-aggregate(states_proj_valid, dissolve = TRUE)
#plot(states_proj_dissolve)
#add buffer around polygons to give a little extra wiggle room when masking veg raster
states_proj_dissolve_buffer<-gBuffer(states_proj_dissolve, byid=TRUE, width=50)
#plot(states_proj_dissolve_buffer)
#now mask raster
veg.raster.mask<-mask(veg.raster_crop, states_proj_dissolve_buffer)
plot(veg.raster.mask)
#save cropped raster
writeRaster(veg.raster_crop, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_AEA_crop.tif",overwrite=TRUE)
#use gdalUtils::gdalwarp; GDAL is better for reprojecting rasters, and much faster than projectRaster(), when files are large
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_AEA_crop.tif",
dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_latlong_crop.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",overwrite=TRUE,verbose=TRUE)
#save masked raster
writeRaster(veg.raster.mask, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_AEA_mask.tif",overwrite=TRUE)
#use gdalUtils::gdalwarp; GDAL is better for reprojecting rasters, and much faster than projectRaster(), when files are large
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_AEA_mask.tif",
dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_latlong_mask.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",overwrite=TRUE,verbose=TRUE)
#read in cropped raster in lat/long
veg.raster.mask.latlong<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_latlong_mask.tif")
#ratify raster (function for defining raster values as categorical, i.e., factor levels)
r <- veg.raster.mask.latlong
r <- ratify(r)
rat <- levels(r)[[1]]
#read in attribute table
LFattributes<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LF2016_EVT_200_CONUS/CSV_Data/LF16_EVT_200.csv")
#subset LFattributes
LFattributes.sub<-subset(LFattributes, VALUE %in% rat$ID)
#create numeric column for EVT_CLASS
LFattributes.sub$EVT_CLASS_value<-as.integer(as.factor(LFattributes.sub$EVT_CLASS))
unique(LFattributes.sub$EVT_CLASS_value)
#get data.frame of Values and EVT_CLASS_value
EVT_CLASS.df<-unique(LFattributes.sub[,c("EVT_CLASS","VALUE","EVT_CLASS_value")])
#reclassify values
reclass.df <- data.frame(id=EVT_CLASS.df$VALUE, v=EVT_CLASS.df$EVT_CLASS_value)
#fix NA
#reclass.df$v<-ifelse(is.na(reclass.df$v),-9999,reclass.df$v)
reclass.r <- subs(r, reclass.df,subsWithNA=FALSE)
reclass.rat<- ratify(reclass.r)
rat <- levels(reclass.rat)[[1]]
#fix NA
LFattributes.sub$EVT_CLASS_value<-ifelse(is.na(LFattributes.sub$EVT_CLASS_value),-9999,LFattributes.sub$EVT_CLASS_value)
#make small df to merge
LFattributes.sub.small<-unique(LFattributes.sub[,c("EVT_CLASS","EVT_CLASS_value")])
names(LFattributes.sub.small)<-c("Ecosystem_type","ID")
rat_merge<-merge(rat, LFattributes.sub.small, by="ID",all.x=TRUE)
#rat$ID<-as.integer(unique(LFattributes.sub$EVT_CLASS_value))
#rat$Ecosystem_type<-unique(as.character(EVT_CLASS.df$EVT_CLASS))
rat_merge$band<-as.integer(rat_merge$ID)
#set factor levels
levels(reclass.r) <- rat_merge
#write raster
writeRaster(reclass.r, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask.tif",overwrite=TRUE)
#define veg class colors
myColors<-c("forestgreen", "lightgreen","seagreen", "goldenrod2", "purple","blue","orange","skyblue","salmon","cadetblue","gray40")
#save to not have to evaluate later (takes long time!)
png(filename="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_3_Land_Fire_2016_veg_layer.png",width=7, height=8, units="in", res=300)
plot(reclass.r,col=myColors,legend=FALSE)
legend("topleft", legend=unique(rat_merge$Ecosystem_type),fill=myColors)
dev.off()
#Load the saved image of raster veg layer
include_graphics("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_3_Land_Fire_2016_veg_layer.png")
#load elevation raster layer
elev.raster<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LF2020_Elev_220_CONUS/Tif/LC20_Elev_220.tif")
#get extent of basemap
basemapExt<-attr(basemap, "bb")
#convert map extent from lat/long to UTM
basemapExt.df<-data.frame("long"=c(basemapExt$ll.lon, basemapExt$ur.lon),"lat"=c(basemapExt$ll.lat, basemapExt$ur.lat))
basemap_extent_sp<-SpatialPoints(cbind(basemapExt.df$long, basemapExt.df$lat), proj4string=CRS("+proj=longlat"))
#project to AEA
basemap_extent_AEA <- spTransform(basemap_extent_sp, projection(elev.raster))
#crop veg raster
elev.raster_crop<-crop(elev.raster, extent(basemap_extent_AEA))
#reproject sharp_patches_sub
states_proj<-spTransform(states.sub, CRS(projection(elev.raster_crop)))
#dissolve states into one polygon, but first fix self-intersection regions with gBuffer, width=0
states_proj_valid<-gBuffer(states_proj, byid=TRUE, width=0)
#dissolve using sp::aggregate
states_proj_dissolve<-aggregate(states_proj_valid, dissolve = TRUE)
#plot(states_proj_dissolve)
#add buffer around polygons to give a little extra wiggle room when masking veg raster
states_proj_dissolve_buffer<-gBuffer(states_proj_dissolve, byid=TRUE, width=50)
#plot(sharp_patches_sub_proj_dissolve_buffer)
#now mask raster
elev.raster.mask<-mask(elev.raster_crop, states_proj_dissolve_buffer)
#save cropped raster
writeRaster(elev.raster_crop, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_AEA_crop.tif",overwrite=TRUE)
#use gdalUtils::gdalwarp; GDAL is better for reprojecting rasters, and much faster than projectRaster(), when files are large
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_AEA_crop.tif",
dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_crop.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",overwrite=TRUE,verbose=TRUE)
#save masked raster
writeRaster(elev.raster.mask, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_AEA_mask.tif",overwrite=TRUE)
#use gdalUtils::gdalwarp; GDAL is better for reprojecting rasters, and much faster than projectRaster(), when files are large
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_AEA_mask.tif",
dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",overwrite=TRUE,verbose=TRUE)
#plot elevation
elev.raster.mask.latlong<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask.tif")
#save to not have to evaluate later (takes long time!)
png(filename="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_4_Land_Fire_2016_elev_layer.png",width=7, height=8, units="in", res=300)
plot(elev.raster.mask.latlong, col=parula(100))
dev.off()
#Load the saved image of raster veg layer
include_graphics("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_4_Land_Fire_2016_elev_layer.png")
#add PointID column
count.data$PointID<-paste("Point",seq(1,nrow(count.data)),sep="_")
#get all unique sampling locations
sampling.locs<-unique(count.data[,c("PointID","Longitude","Latitude")])
sampling.locs$ID<-seq(1,length(row.names(sampling.locs)),by=1)
#add buffers of 750-m radii to sampling locs
# circular buffers with a radius of 1000 m
buffers <- dismo::circles(sampling.locs[c("Longitude","Latitude")], d=5000, lonlat=TRUE, dissolve=FALSE)
#coerce to polygons
buffers.polygon <- polygons(buffers)
reclass.r<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask.tif")
#extract values (IDs are circular buffer polygons)
extracted.veg.cell.counts<-raster::extract(reclass.r, buffers.polygon, factors=TRUE, df=TRUE)
names(extracted.veg.cell.counts)[names(extracted.veg.cell.counts)=="category"]<-"Ecosystem_type"
#make ID and Vegetation_class factors
extracted.veg.cell.counts$ID<-as.factor(extracted.veg.cell.counts$ID)
extracted.veg.cell.counts$Ecosystem_type<-as.factor(extracted.veg.cell.counts$Ecosystem_type)
#add CellCount column
extracted.veg.cell.counts$CellCount<-1
#get total cell count per ID
total.cell.count<-aggregate(CellCount~ID, data=extracted.veg.cell.counts, FUN=sum)
names(total.cell.count)[names(total.cell.count)=="CellCount"]<-"TotalCellCount"
#aggregate to get proportions
extracted.veg.aggregate<-stats::aggregate(CellCount~ID+Ecosystem_type, data=extracted.veg.cell.counts, FUN=sum)
#merge
extracted.merge<-merge(extracted.veg.aggregate, total.cell.count, by=c("ID"),all.x=TRUE)
#Compute proportions (CellCount/TotalCellCount)
extracted.merge$Ecosystem_type_proportion<-extracted.merge$CellCount/extracted.merge$TotalCellCount
#Now merge back with sampling locs
veg.proportions.df<-merge(sampling.locs, extracted.merge, by="ID",all.x=TRUE)
#melt and cast
veg.data.melt<-melt(veg.proportions.df, id.vars=c("PointID","ID","Longitude","Latitude", "Ecosystem_type"), measure.vars=c("Ecosystem_type_proportion"))
#cast and fill any NAs with 0s
pred.veg.proportions.df.cast<-dcast(PointID+ID+Longitude+Latitude~Ecosystem_type,data=veg.data.melt, fill=0)
#remove NA column
pred.veg.proportions.df.cast$`NA`<-NULL
#merge with count data
count.data.merge<-merge(count.data, veg.proportions.df[,c("PointID","Ecosystem_type","Ecosystem_type_proportion")], by=c("PointID"),all.x=TRUE)
#save .csv
write.csv(count.data.merge, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Detection_Data_with_EcoSys_covs.csv",row.names=FALSE)
#load elevation data
elev.raster.mask.latlong<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask.tif")
# get elevation at sampling locations
spatialPts<- SpatialPoints(cbind(count.data$Longitude, count.data$Latitude), proj4string=CRS(projection(elev.raster.mask.latlong)))
#extract values (IDs are circular buffer polygons)
extracted.elev.cell.values<-raster::extract(elev.raster.mask.latlong, spatialPts, fun=mean, factors=FALSE, df=TRUE)
#make ID and Vegetation_class factors
extracted.elev.cell.values$ID<-as.factor(extracted.elev.cell.values$ID)
#add PointID
extracted.elev.cell.values$PointID<-paste("Point",seq(1,nrow(count.data)),sep="_")
#merge with count data
elev.data.merge<-merge(count.data, extracted.elev.cell.values[,c("PointID","LandFire_Elevation_latlong_mask")], by=c("PointID"),all.x=TRUE)
#save .csv
write.csv(extracted.elev.cell.values, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Sampling_Locs_elevation.csv",row.names=FALSE)
#read in new data with Veg layer covariates
detectionData_with_veg_covs<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Detection_Data_with_EcoSys_covs.csv")
#melt and cast
landcover.melt<-melt(detectionData_with_veg_covs, id.vars=c("PointID","Hexagon","Jun", "Jul","Aug","Longitude","Latitude","Visit_1","Visit_2","Visit_3", "Ecosystem_type"), measure.vars=c("Ecosystem_type_proportion"))
#cast and fill any NAs with 0s
lancover.proportions.cast<-dcast(PointID+Hexagon+Longitude+Latitude+Jun+Jul+Aug+Visit_1+Visit_2+Visit_3~Ecosystem_type,data=landcover.melt, fill=0)
#load elevation data
elev.df<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Sampling_Locs_elevation.csv")
#add other covs
covs.merge.1<-merge(lancover.proportions.cast, elev.df, by="PointID",all.x=TRUE)
#fix names
names(covs.merge.1)[names(covs.merge.1)=="LandFire_Elevation_latlong_mask"]<-"Elevation_m"
#remove Covariate == NA
covs.merge.1$`NA`<-NULL
#save covs.merge.1
write.csv(covs.merge.1, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Detection_data_ALL_Covs.csv",row.names=FALSE)
#build prediction surface (and save .csv)
#create a new blank raster with all values = 1 with dimensions for prediction
veg.raster.mask.latlong.class<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask.tif")
#create a raster that is not quite so hi-res as original raster (to use for extraction)
#compute 100-m resolution
res100<-res(veg.raster.mask.latlong.class)[1]*100/30
#downsample raster with gdalwarp (use r="mode" for categorical data)
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask.tif",
dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask_100m.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",tr=c(res100,res100),r="mode",overwrite=TRUE,verbose=TRUE)
veg.raster.mask.latlong_100<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask_100m.tif")
#now compute 5000-m resolution to get polygons for extraction
new.res<-res(veg.raster.mask.latlong.class)[1]*5000/30
#downsample raster with gdalwarp (use r="mode" for categorical data)
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask.tif",dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask_5000m.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",tr=c(new.res,new.res),r="mode",overwrite=TRUE,verbose=TRUE)
veg.raster.mask.latlong_5000<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_EcoSys_EVT_Class_latlong_mask_5000m.tif")
plot(veg.raster.mask.latlong_5000, col=parula(13))
#
# plot(veg.raster.mask.latlong_300)
# dim(veg.raster.mask.latlong_300)
# res(veg.raster.mask.latlong_300)
#ratify raster (function for defining raster values as categorical, i.e., factor levels)
r_5000 <- veg.raster.mask.latlong_5000
r_5000_rat <- ratify(r_5000)
rat_5000 <- levels(r_5000_rat)[[1]]
#read in attribute table
rat_merge_5000<-merge(rat_5000, LFattributes.sub.small, by="ID",all.x=TRUE)
rat_merge_5000$band<-as.integer(rat_merge_5000$ID)
#set factor levels
levels(veg.raster.mask.latlong_5000) <- rat_merge_5000
new.raster.df<-as.data.frame(rasterToPoints(veg.raster.mask.latlong_5000))
colnames(new.raster.df)<-c("Longitude","Latitude","Value")
###############################################################################
#get all unique sampling locations
pred.sampling.locs<-unique(new.raster.df[,c("Longitude","Latitude")])
pred.sampling.locs$ID<-seq(1,length(row.names(pred.sampling.locs)),by=1)
pred.sampling.locs$ID<-as.factor(as.character(pred.sampling.locs$ID))
# circular buffers with a radius of 100m
pred.buffers <- dismo::circles(pred.sampling.locs[,c("Longitude","Latitude")], d=5000, lonlat=TRUE, dissolve=FALSE)
#coerce to polygons
pred.buffers.polygon <- polygons(pred.buffers)
#save as Rdata
# saveRDS(pred.buffers.polygon, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Predicted_Polygons.rds")
#
# pred.buffers.polygon_test<-readRDS("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Predicted_Polygons.rds")
##############################################################################
#Vegetation Class proportions
#create empty list
save.proportions<-list()
#loop through and extract proportions
for(i in 1:length(pred.buffers.polygon)){
print(i)
new.poly<-pred.buffers.polygon[i]
pred.veg.cell.counts.new<-raster::extract(veg.raster.mask.latlong.class, new.poly, factors=TRUE, df=TRUE,na.rm=TRUE)
#make ID (cell location ID) and Vegetation_class factors
pred.veg.cell.counts.new$ID<-as.character(i)
names(pred.veg.cell.counts.new)[names(pred.veg.cell.counts.new)=="category"]<-"Ecosystem_type"
#add CellCount column
pred.veg.cell.counts.new$CellCount<-1
#get total cell count per Vegetation_class
total.cell.count.pred.new<-stats::aggregate(CellCount~ID, data=na.omit(pred.veg.cell.counts.new), FUN=sum)
names(total.cell.count.pred.new)[names(total.cell.count.pred.new)=="CellCount"]<-"TotalCellCount"
#aggregate to get proportions
pred.veg.aggregate.new<-stats::aggregate(CellCount~ID+Ecosystem_type, data=pred.veg.cell.counts.new, FUN=sum)
#merge
pred.veg.merge<-merge(pred.veg.aggregate.new, total.cell.count.pred.new, by=c("ID"),all.x=TRUE)
#Compute proportions (CellCount/TotalCellCount)
pred.veg.merge$Ecosystem_type_proportion<-pred.veg.merge$CellCount/pred.veg.merge$TotalCellCount
save.proportions<-rbind(save.proportions, pred.veg.merge)
}
#save as .csv
write.csv(save.proportions, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Predicted_Surface_proportions.csv", row.names=FALSE)
pred.surface.proportions<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Predicted_Surface_proportions.csv")
#extract values (IDs are circular buffer polygons)
#pred.veg.cell.counts<-raster::extract(veg.raster.mask.latlong.class, pred.buffers.polygon, factors=TRUE, df=TRUE)
#Now merge back with sampling locs
pred.veg.proportions.df<-merge(pred.surface.proportions, pred.sampling.locs, by="ID",all.x=TRUE)
#melt and cast
pred.veg.proportions.df.melt<-melt(pred.veg.proportions.df, id.vars=c("ID","Longitude","Latitude", "Ecosystem_type"), measure.vars=c("Ecosystem_type_proportion"))
#cast and fill any NAs with 0s
pred.veg.proportions.df.cast<-dcast(ID+Longitude+Latitude~Ecosystem_type,data=pred.veg.proportions.df.melt, fill=0)
#remove NA column
pred.veg.proportions.df.cast$`NA`<-NULL
#dim(pred.veg.proportions.df.cast)
#unique(pred.veg.proportions.df.cast$ID)
#save predictive surface as .csv
write.csv(pred.veg.proportions.df.cast, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Predicted_Surface__Landfire_proportions_5000m.tif", row.names=FALSE)
#elevation raster
elev.raster.mask.latlong<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask.tif")
#downsample from 30 to 1000m resolution
gdalUtils::gdalwarp(srcfile="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask.tif",
dstfile=file.path("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask_5000.tif"),t_srs="+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0",tr=c(new.res,new.res),r="average",overwrite=TRUE,verbose=TRUE)
elev.raster.mask.latlong_5000<-raster("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/LandFire_Elevation_latlong_mask_5000.tif")
elev.raster.df<-as.data.frame(rasterToPoints(elev.raster.mask.latlong_5000))
colnames(elev.raster.df)<-c("Longitude","Latitude","Elevation_m")
#merge covariates
all.covs.merge<-Reduce(function(x, y) merge(x, y, by=c("Latitude","Longitude"), all.x=TRUE), list(pred.veg.proportions.df.cast, elev.raster.df))
write.csv(all.covs.merge, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/ALL_covs_pred_surface.csv", row.names=FALSE)
# #read in new data with Veg layer covariates
all.data<-na.omit(read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Detection_data_ALL_Covs.csv"))
#reduce to include only variables we model (USE LFattributes for 12 landcover types)
#Open Tree Canopy = Evergreen Open Tree Canopy
covariate.df<-all.data[,c("Elevation_m",
"Closed.tree.canopy",
#"Dwarf.shrubland",
"Herbaceous.grassland",
"Herbaceous.shrub.steppe",
"No.Dominant.Lifeform",
"Non.vegetated",
"Open.tree.canopy",
"Open.Tree.Canopy",
"Shrubland",
"Sparse.tree.canopy",
"Sparsely.vegetated"
)]
#scale covs
covariate.df<-sapply(covariate.df, function(x) scale(x) )
#create a matrix of these data
cov_matrix <-as.matrix(covariate.df)
#get correlation matrix
cov_cor_matrix <-Hmisc::rcorr(cov_matrix)
cor_mat.df<-as.data.frame(cov_cor_matrix[1])
#plot the correlation matrix with GGally package
corrPlot<-GGally::ggcorr(cor_mat.df, midpoint=0,label=TRUE)
#save plot
jpeg(file = "/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_5_Correlation_matrix_covs.jpeg", width=12, height=12, units="in",res=600)
print(corrPlot)
dev.off()
#show plot by loading saved image
include_graphics("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_5_Correlation_matrix_covs.jpeg")
#read in detection data with covariates
all.data<-na.omit(read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Detection_data_ALL_Covs.csv"))
#make list of detection process covariates (non-factors only)
detformulaList<-c(~Elevation_m, ~Closed.tree.canopy, ~Herbaceous.grassland,~Herbaceous.shrub.steppe, ~No.Dominant.Lifeform, ~Non.vegetated, ~Open.tree.canopy, ~Open.Tree.Canopy,~Shrubland,~Sparse.tree.canopy,
~Sparsely.vegetated)
#build new unmarked frame
new.umf<-makePOccu_umf_with_covs(DataIn=all.data)
#get obsCovs as data.frame
obsCovs.df<-as.data.frame(new.umf@obsCovs)
#empty list to fill with results
occu.mod.save<-list()
#create empty list to save predicted detection Probs
DetCovariatePred<-list()
#for loop to iterate over detection covariates and produce predicted estimates for detection prob
for(j in 1:length(detformulaList)){
#print(detformulaList[[j]])
#fit model
new.occ_model <- occu(detformulaList[[j]]~ 1, data=new.umf)
#get det covariate name
varName<-gsub("~","",as.character(detformulaList[[j]]))[2]
#get range of values from data to simulate new data
varData<-obsCovs.df[,names(obsCovs.df)==varName]
#simulate new data
sim.data<-data.frame(seq(min(varData,na.rm=TRUE), max(varData,na.rm=TRUE),length.out=100))
colnames(sim.data)<-c(varName)
#get predicted values using sim.data
pred.df<-predict(new.occ_model, type="det", newdata=sim.data, appendData=TRUE)
colnames(pred.df)[5]<-"det_cov"
#get original covariate data
cov.data<-all.data[,c(print(varName))]
meanCov <- mean(cov.data)
sdCov <- sd(cov.data)
#backtransform scaled variable
pred.df$det_cov_bt<- t((t(pred.df$det_cov) * sdCov) + meanCov)
#add column with covariate name
pred.df$CovariateName<-varName
DetCovariatePred<-rbind(DetCovariatePred, pred.df)
#compile covariates for each species
occu.mod.save<-rbind(occu.mod.save, DetCovariatePred)
}
## [1] "Elevation_m"
## [1] "Closed.tree.canopy"
## [1] "Herbaceous.grassland"
## [1] "Herbaceous.shrub.steppe"
## [1] "No.Dominant.Lifeform"
## [1] "Non.vegetated"
## [1] "Open.tree.canopy"
## [1] "Open.Tree.Canopy"
## [1] "Shrubland"
## [1] "Sparse.tree.canopy"
## [1] "Sparsely.vegetated"
#make CovariateName a factor
occu.mod.save$CovariateName<-factor(occu.mod.save$CovariateName, levels=c("Elevation_m","Closed.tree.canopy", "Herbaceous.grassland","Herbaceous.shrub.steppe","Open.tree.canopy","Open.Tree.Canopy","Shrubland","Sparse.tree.canopy","Sparsely.vegetated","Non.vegetated","No.Dominant.Lifeform"))
#now plot
#plot p(Occupancy) vs. Vegetation class proportions
det.prob.plot<-ggplot(data=occu.mod.save, aes(x=det_cov_bt, y=Predicted))+
geom_point(aes(color=CovariateName),alpha=0.9,size=1)+
geom_smooth(method = "glm", formula = y~x, method.args = list(family = binomial), aes(color=CovariateName, fill=CovariateName),alpha=0.2,fullrange=FALSE)+
# scale_color_manual(values=myColors)+
# scale_fill_manual(values=myColors)+
#ylim(c(0,1))+
#coord_cartesian(expand = FALSE, xlim=c(0,1),ylim=c(0.99,1))+
theme(
panel.background = element_rect(fill="white",color="black"),
panel.border = element_rect(fill="transparent",color="black"),
axis.text.x = element_text(size=8),
axis.text.y = element_text(size=8),
legend.position="bottom"
)+
labs(x="Observation Covariate", y="Detection Probability")
#facet over Vegetation_class
det.prob.plot.facet<-det.prob.plot+facet_wrap(CovariateName~., scales="free",ncol=4)
print(det.prob.plot.facet)
#create filename with timestamp
new.filename<-paste("Fig_6_Detection_Probability_covariates",".png",sep="")
ggsave(det.prob.plot.facet, file=paste("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/",new.filename, sep=""),width=9, height=9, dpi=600)
#build new unmarked frame
new.umf<-makePOccu_umf_with_covs(DataIn=all.data)
#fit model with Veg covariates
mod.global<-NULL
mod.global<-occu(~Visit ~Elevation_m+
Closed.tree.canopy+
#Dwarf.shrubland+
Herbaceous.grassland+
#Herbaceous.shrub.steppe+
Open.tree.canopy+
Open.Tree.Canopy+
#Shrubland+
#Sparse.tree.canopy+
Sparsely.vegetated+
#Non.vegetated+
No.Dominant.Lifeform
, data=new.umf,se=TRUE)
# #model selection step
# dredge.mod <- dredge(mod.global)
# dredge.mod
# dredge.mod.top<-subset(dredge.mod, delta < 4)
# Visualize the model selection table:
# par(mar = c(3,5,6,4))
# plot(dredge.mod.top, labAsExpr = TRUE)
# Model average models with delta AICc < 4
# mod.average<-model.avg(dredge.mod.top)
# summary(mod.average)
# Model-averaged coefficients:
# (full average)
# Estimate Std. Error z value Pr(>|z|)
# psi(Int) -5.455e-01 3.168e-01 1.722 0.08503 .
# psi(Open.tree.canopy) 2.971e+00 1.243e+00 2.390 0.01687 *
# p(Int) 8.212e-01 2.200e-01 3.732 0.00019 ***
# p(VisitVisit_2) -3.394e-01 2.623e-01 1.294 0.19565
# p(VisitVisit_3) -1.754e+00 2.788e-01 6.291 < 2e-16 ***
# psi(Open.Tree.Canopy) 2.348e+00 4.627e+00 0.507 0.61182
# psi(No.Dominant.Lifeform) -1.958e-01 5.778e-01 0.339 0.73475
# psi(Sparsely.vegetated) 1.143e+01 3.553e+01 0.322 0.74773
# psi(Closed.tree.canopy) 3.487e-02 2.479e-01 0.141 0.88814
# psi(Herbaceous.grassland) -1.499e-02 2.625e-01 0.057 0.95445
# psi(Non.vegetated) -1.087e-02 4.705e-01 0.023 0.98157
# psi(Elevation_m) -6.114e-06 2.349e-04 0.026 0.97923
#
# (conditional average)
# Estimate Std. Error z value Pr(>|z|)
# psi(Int) -5.455e-01 3.168e-01 1.722 0.08503 .
# psi(Open.tree.canopy) 2.971e+00 1.243e+00 2.390 0.01687 *
# p(Int) 8.212e-01 2.200e-01 3.732 0.00019 ***
# p(VisitVisit_2) -3.394e-01 2.623e-01 1.294 0.19565
# p(VisitVisit_3) -1.754e+00 2.788e-01 6.291 < 2e-16 ***
# psi(Open.Tree.Canopy) 6.622e+00 5.663e+00 1.169 0.24226
# psi(No.Dominant.Lifeform) -7.887e-01 9.367e-01 0.842 0.39979
# psi(Sparsely.vegetated) 4.352e+01 5.841e+01 0.745 0.45617
# psi(Closed.tree.canopy) 2.125e-01 5.803e-01 0.366 0.71425
# psi(Herbaceous.grassland) -1.251e-01 7.490e-01 0.167 0.86738
# psi(Non.vegetated) -9.173e-02 1.364e+00 0.067 0.94639
# psi(Elevation_m) -4.508e-05 6.364e-04 0.071 0.94352
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#refit using significant covariates
#fit model with Veg covariates
mod.global<-NULL
mod.global<-occu(~Visit ~Elevation_m+
Closed.tree.canopy+
#Dwarf.shrubland+
#Herbaceous.grassland+
#Herbaceous.shrub.steppe+
Open.tree.canopy+
Open.Tree.Canopy
#Shrubland+
#Sparse.tree.canopy+
#Sparsely.vegetated+
#Non.vegetated
#No.Dominant.Lifeform
, data=new.umf,se=TRUE)
mod.gof<-NULL
mod.gof<- try(mb.gof.test(mod.global, nsim = 10, plot.hist = FALSE, report = NULL, parallel = FALSE))
#get c-hat
if(!is.null(mod.gof)){
mod.c.hat<-mod.gof$c.hat.est
} else {
mod.c.hat<-NA
}
#get predicted estimates
mod.predict<-predict(mod.global, type="state",appendData=TRUE)
#add original unscaled covariates
#mod.predict<-cbind(mod.predict, all.data)
#add GOF_cHat
mod.predict$GOF_c_hat<-mod.c.hat
#simplify
#mod.predict.sub<-unique(mod.predict[,c("PointID","Longitude","Latitude","Predicted","SE","lower","upper","GOF_c_hat","Elevation_m","Closed.tree.canopy","Herbaceous.grassland","Herbaceous.shrub.steppe","Open.tree.canopy","Open.Tree.Canopy","Shrubland","Sparse.tree.canopy","Sparsely.vegetated","Non.vegetated","No.Dominant.Lifeform")])
mod.predict.sub<-unique(mod.predict[,c("PointID","Longitude","Latitude","Predicted","SE","lower","upper","GOF_c_hat","Elevation_m","Closed.tree.canopy","Open.tree.canopy","Open.Tree.Canopy")])
#########################################################################
#Plot the beta coefficients
#get model summary
mod.summary<-summary(mod.global)
##
## Call:
## occu(formula = ~Visit ~ Elevation_m + Closed.tree.canopy + Open.tree.canopy +
## Open.Tree.Canopy, data = new.umf, se = TRUE)
##
## Occupancy (logit-scale):
## Estimate SE z P(>|z|)
## (Intercept) -1.045626 0.497773 -2.101 0.03568
## Elevation_m -0.000223 0.000711 -0.313 0.75403
## Closed.tree.canopy 0.490350 0.677592 0.724 0.46927
## Open.tree.canopy 4.696161 1.643803 2.857 0.00428
## Open.Tree.Canopy 7.815849 6.676846 1.171 0.24176
##
## Detection (logit-scale):
## Estimate SE z P(>|z|)
## (Intercept) 0.821 0.220 3.73 1.90e-04
## VisitVisit_2 -0.339 0.262 -1.29 1.96e-01
## VisitVisit_3 -1.754 0.279 -6.29 3.17e-10
##
## AIC: 786.7018
## Number of sites: 266
## optim convergence code: 0
## optim iterations: 58
## Bootstrap iterations: 0
new.coefs<-as.data.frame(mod.summary$state)
new.coefs$Variable<-row.names(new.coefs)
row.names(new.coefs)<-NULL
#coompute 95% CIs
new.coefs$`Lower_95%_CI` <- new.coefs$Estimate - 1.96*new.coefs$SE
new.coefs$`Upper_95%_CI` <- new.coefs$Estimate + 1.96*new.coefs$SE
#first remove intercepts
coefs.occu.save<-subset(new.coefs, Variable != "(Intercept)")
#add ZeroCross column
coefs.occu.save$ZeroCross<-ifelse(coefs.occu.save$`Lower_95%_CI`>0 | coefs.occu.save$`Upper_95%_CI` < 0,"No_Zero_Cross","Zero_Cross")
#make a factor
coefs.occu.save$ZeroCross<-as.factor(coefs.occu.save$ZeroCross)
#sort Variables
coefs.occu.save.order<-coefs.occu.save[order(coefs.occu.save$Estimate, decreasing = FALSE),]
#set factor levels for Variable
coefs.occu.save.order$Variable<-factor(coefs.occu.save.order$Variable, levels=unique(coefs.occu.save.order$Variable))
#set colors
myBetaColors<-c("royalblue2","gray60")
#plot beta coefficients
betaCoefPlot_occu<-ggplot(data=coefs.occu.save.order, aes(x=Variable, y=Estimate))+
geom_hline(yintercept=0,linetype=2)+
geom_errorbar(aes(ymin=`Lower_95%_CI`, ymax=`Upper_95%_CI`, color = ZeroCross),width=0)+
geom_point(aes(color=ZeroCross),alpha=0.8)+
scale_y_continuous(limits=c(-5000,5000))+
#coord_cartesian(ylim=c(-180,180))+
scale_color_manual(values=myBetaColors)+
coord_flip(ylim=c(-10,10))+
#scale_color_gradient2(low="red",mid="gray40",high="royalblue2",midpoint = 0)+
theme(legend.position="none",
panel.background = element_rect(fill="white",color="black"),
panel.border = element_rect(fill="transparent",color="black"))+
labs(y="Beta Coefficient Estimate", x="Site-level Covariate")
betaCoefPlot_occu
ggsave(betaCoefPlot_occu, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_7_Beta_coefficient_plot.png",width=6, height=6,dpi=600)
#melt
mod.predict.melt<-melt(mod.predict.sub, id.vars=c("PointID","Predicted","SE","lower","upper"), measure.vars=c("Elevation_m","Closed.tree.canopy","Open.tree.canopy","Open.Tree.Canopy"), variable.name = "Variable", value.name="value")
#define veg class colors
#myColors<-c("#538233","#a9d08e", "#f9bf8e", "#feff00", "#01b0f0","#0070c0","#000000","#a6a6a6","magenta2","royalblue3","seagreen4","orangered3")
#levels(mod.predict.melt$Variable)
#plot p(Occupancy) vs. Vegetation class proportions
mod.occu.plot<-ggplot(data=mod.predict.melt, aes(x=value, y=Predicted,group=Variable))+
geom_point(aes(color=Variable),alpha=0.3,size=1)+
stat_smooth(method = "glm", formula = y~x, method.args = list(family = binomial), aes(color=Variable, fill=Variable),alpha=0.2,fullrange=FALSE,se=TRUE)+
# scale_color_manual(values=myColors)+
# scale_fill_manual(values=myColors)+
#ylim(c(0,1))+
theme(
panel.background = element_rect(fill="white",color="black"),
panel.border = element_rect(fill="transparent",color="black"),
axis.text.x = element_text(size=8),
axis.text.y = element_text(size=8),
legend.position="bottom"
)+
labs(x="Variable", y="Predicted p(Occupancy)")
#facet over Vegetation_class
mod.occu.plot.facet<-mod.occu.plot+facet_wrap(Variable~.,scales="free",ncol=2)
mod.occu.plot.facet
#create filename with timestamp
new.filename<-paste("Fig_8_Predicted_Occupancy_models_with_veg_class",".png",sep="")
ggsave(mod.occu.plot.facet, file=paste("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/",new.filename, sep=""),width=12, height=12, dpi=600)
#load predictive surface
pred_surface<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/ALL_covs_pred_surface.csv")
#remove unwanted columns
# pred_surface$Dwarf.shrubland<-NULL
# pred_surface$Herbaceous.shrub.steppe<-NULL
# pred_surface$No.Dominant.Lifeform<-NULL
# pred_surface$Non.vegetated<-NULL
# pred_surface$Shrubland<-NULL
# pred_surface$Sparse.tree.canopy<-NULL
# pred_surface$Sparsely.vegetated<-NULL
#get predicted estimates of avian occupancy as a function of vegetation cover on map
occ_pred <- predict(mod.global,
newdata = as.data.frame(pred_surface),
type = "state", appendData=TRUE)
suppressMessages({
# add to prediction surface
pred_occ <- bind_cols(pred_surface,
occ_prob = occ_pred$Predicted,
occ_se = occ_pred$SE) %>%
select(Latitude, Longitude, occ_prob, occ_se)
})
#melt to plot in ggplot
pred_occ.melt<-melt(pred_occ, id.vars=c("Latitude","Longitude"),
variable.name = "Measure",value.name="p(Occupancy)")
map.occu.plot<-ggmap(basemap,darken = c(0.4, "black"))+
geom_tile(data=pred_occ.melt, aes(x=Longitude, y=Latitude, fill=`p(Occupancy)`,color=`p(Occupancy)`))+
geom_map(data=states.poly, map=states.poly, aes(y=lat, x=long, map_id=id),color=alpha("white",0.3),fill="transparent", inherit.aes = FALSE,size=0.1)+
scale_fill_gradientn(colors=ocean.thermal(100),na.value = "transparent",limits=c(0,1))+
scale_color_gradientn(colors=ocean.thermal(100),na.value = "transparent",limits=c(0,1))+
labs(x="Longitude",y="Latitude")+
theme(axis.text=element_text(size=12),
axis.title=element_text(size=14),
axis.text.x=element_text(size=8),
axis.text.y=element_text(size=8),
panel.border=element_rect(fill="transparent", color="black"),
legend.position = "right")+
ggtitle(paste("WPWI"," - Predicted probability of occupancy",sep=""))+
#geom_text_repel(check_overlap = FALSE, size=3, nudge.y=-10, nudge.x=-10,aes(x=Longitude, y=Latitude,color=PatchID, label=PatchID),data=PatchID_labels)+
#guides(fill = guide_legend(title = "National Wildlife Refuge", label = FALSE))+
ggsn::scalebar(x.min=mapExtent$ll.lon, x.max=mapExtent$ur.lon, y.min=mapExtent$ll.lat, y.max=mapExtent$ur.lat,transform=TRUE, dist_unit="km",dist=100, st.dist=0.03, height = 0.015, anchor=c(x=-70.5,y=38.55), border.size=0.5,st.size=3)
map.occu.plot.facet.save<-map.occu.plot+facet_wrap(Measure~.,ncol=1)
#create filename with timestamp
new.filename<-paste(paste("Fig_9_WPWI_","Map_Predicted_Occupancy",sep=""),".png",sep="")
ggsave(map.occu.plot.facet.save, file=paste("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/",new.filename, sep=""),width=14, height=8, dpi=600)
print(map.occu.plot.facet.save)
#read in detection data with covariates
all.data<-na.omit(read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/Detection_data_ALL_Covs.csv"))
#build new unmarked frame
new.umf<-makePCount_umf_with_covs(DataIn=all.data)
#fit model with Veg covariates
mod.global<-NULL
mod.global<-pcount(~Visit ~Elevation_m+
Closed.tree.canopy+
#Dwarf.shrubland+
Herbaceous.grassland+
#Herbaceous.shrub.steppe+
Open.tree.canopy+
Open.Tree.Canopy+
#Shrubland+
#Sparse.tree.canopy+
Sparsely.vegetated+
#Non.vegetated+
No.Dominant.Lifeform
, data=new.umf,se=TRUE)
# #model selection step
# dredge.mod <- dredge(mod.global)
# dredge.mod
# dredge.mod.top<-subset(dredge.mod, delta < 4)
# Visualize the model selection table:
# par(mar = c(3,5,6,4))
# plot(dredge.mod.top, labAsExpr = TRUE)
# Model average models with delta AICc < 4
# mod.average<-model.avg(dredge.mod.top)
# summary(mod.average)
# Model-averaged coefficients:
# (full average)
# Estimate Std. Error z value Pr(>|z|)
# lam(Int) 2.096e-02 3.008e-01 0.070 0.94444
# lam(Closed.tree.canopy) 3.274e-01 3.491e-01 0.938 0.34829
# lam(Open.tree.canopy) 3.552e+00 5.409e-01 6.567 < 2e-16 ***
# lam(Open.Tree.Canopy) 5.794e+00 2.589e+00 2.238 0.02522 *
# lam(Sparsely.vegetated) 3.367e+01 1.542e+01 2.183 0.02902 *
# p(Int) -4.936e-01 1.751e-01 2.818 0.00483 **
# p(VisitVisit_2) -3.846e-01 1.205e-01 3.191 0.00142 **
# p(VisitVisit_3) -1.705e+00 1.621e-01 10.517 < 2e-16 ***
# lam(Herbaceous.grassland) -1.406e-01 3.312e-01 0.425 0.67111
# lam(No.Dominant.Lifeform) -5.116e-02 2.792e-01 0.183 0.85460
# lam(Elevation_m) 1.305e-05 7.074e-05 0.184 0.85368
#
# (conditional average)
# Estimate Std. Error z value Pr(>|z|)
# lam(Int) 0.0209584 0.3007513 0.070 0.94444
# lam(Closed.tree.canopy) 0.5377469 0.2950078 1.823 0.06833 .
# lam(Open.tree.canopy) 3.5520350 0.5408537 6.567 < 2e-16 ***
# lam(Open.Tree.Canopy) 6.0753976 2.3065417 2.634 0.00844 **
# lam(Sparsely.vegetated) 35.1468185 14.0129940 2.508 0.01214 *
# p(Int) -0.4935698 0.1751444 2.818 0.00483 **
# p(VisitVisit_2) -0.3845809 0.1205179 3.191 0.00142 **
# p(VisitVisit_3) -1.7051791 0.1621320 10.517 < 2e-16 ***
# lam(Herbaceous.grassland) -0.4167398 0.4582780 0.909 0.36316
# lam(No.Dominant.Lifeform) -0.2162472 0.5419927 0.399 0.68990
# lam(Elevation_m) 0.0002180 0.0001973 1.105 0.26918
#refit using significant covariates
#fit model with Veg covariates
mod.global<-NULL
mod.global<-pcount(~Visit ~
#Elevation_m+
#Closed.tree.canopy+
#Dwarf.shrubland+
Herbaceous.grassland+
#Herbaceous.shrub.steppe+
Open.tree.canopy
#Open.Tree.Canopy+
#Shrubland+
#Sparse.tree.canopy+
#Sparsely.vegetated+
#Non.vegetated+
#No.Dominant.Lifeform
, data=new.umf,se=TRUE)
mod.gof<-NULL
mod.gof<- Nmix.gof.test(mod.global, nsim = 20, plot.hist = FALSE,report = NULL, parallel = FALSE)
#get c-hat
if(!is.null(mod.gof)){
mod.c.hat<-mod.gof$c.hat.est
} else {
mod.c.hat<-NA
}
#get predicted estimates
mod.predict<-predict(mod.global, type="state",appendData=TRUE)
#add original unscaled covariates
#mod.predict<-cbind(mod.predict, all.data)
#add GOF_cHat
mod.predict$GOF_c_hat<-mod.c.hat
#simplify
mod.predict.sub<-unique(mod.predict[,c("PointID","Longitude","Latitude","Predicted","SE","lower","upper","GOF_c_hat","Elevation_m","Closed.tree.canopy","Herbaceous.grassland","Herbaceous.shrub.steppe","Open.tree.canopy","Open.Tree.Canopy","Shrubland","Sparse.tree.canopy","Sparsely.vegetated","Non.vegetated","No.Dominant.Lifeform")])
# mod.predict.sub<-unique(mod.predict[,c("PointID","Longitude","Latitude","Predicted","SE","lower","upper","GOF_c_hat","Open.tree.canopy","Herbaceous.grassland")])
#########################################################################
#Plot the beta coefficients
#get model summary
mod.summary<-summary(mod.global)
##
## Call:
## pcount(formula = ~Visit ~ Herbaceous.grassland + Open.tree.canopy,
## data = new.umf, se = TRUE)
##
## Abundance (log-scale):
## Estimate SE z P(>|z|)
## (Intercept) 0.421 0.137 3.08 2.08e-03
## Herbaceous.grassland -0.515 0.378 -1.36 1.74e-01
## Open.tree.canopy 2.926 0.384 7.62 2.63e-14
##
## Detection (logit-scale):
## Estimate SE z P(>|z|)
## (Intercept) -0.473 0.173 -2.73 6.29e-03
## VisitVisit_2 -0.389 0.121 -3.22 1.30e-03
## VisitVisit_3 -1.712 0.162 -10.54 5.49e-26
##
## AIC: 1841.402
## Number of sites: 266
## optim convergence code: 0
## optim iterations: 31
## Bootstrap iterations: 0
new.coefs<-as.data.frame(mod.summary$state)
new.coefs$Variable<-row.names(new.coefs)
row.names(new.coefs)<-NULL
#coompute 95% CIs
new.coefs$`Lower_95%_CI` <- new.coefs$Estimate - 1.96*new.coefs$SE
new.coefs$`Upper_95%_CI` <- new.coefs$Estimate + 1.96*new.coefs$SE
#first remove intercepts
coefs.abun.save.sub<-subset(new.coefs, Variable != "(Intercept)")
#add ZeroCross column
coefs.abun.save.sub$ZeroCross<-ifelse(coefs.abun.save.sub$`Lower_95%_CI`>0 | coefs.abun.save.sub$`Upper_95%_CI` < 0,"No_Zero_Cross","Zero_Cross")
#make a factor
coefs.abun.save.sub$ZeroCross<-as.factor(coefs.abun.save.sub$ZeroCross)
#set factor levels for Variable
coefs.abun.save.sub$Variable<-factor(coefs.abun.save.sub$Variable, levels=unique(coefs.abun.save.sub$Variable))
#set colors
myBetaColors<-c("magenta","gray60")
#plot beta coefficients
betaCoefPlot_abun<-ggplot(data=coefs.abun.save.sub, aes(x=Variable, y=Estimate))+
geom_hline(yintercept=0,linetype=2)+
geom_errorbar(aes(ymin=`Lower_95%_CI`, ymax=`Upper_95%_CI`, color = ZeroCross),width=0)+
geom_point(aes(color=ZeroCross),alpha=0.8)+
scale_y_continuous(limits=c(-5000,5000))+
#coord_cartesian(ylim=c(-180,180))+
scale_color_manual(values=myBetaColors)+
coord_flip(ylim=c(-100,100))+
#scale_color_gradient2(low="red",mid="gray40",high="royalblue2",midpoint = 0)+
theme(legend.position="none",
panel.background = element_rect(fill="white",color="black"),
panel.border = element_rect(fill="transparent",color="black"))+
labs(y="Beta Coefficient Estimate", x="Site-level Covariate")
betaCoefPlot_abun
ggsave(betaCoefPlot_abun, file="/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/Fig_10_Beta_coefficient_plot_abundance.png",width=7, height=6,dpi=600)
#melt
# mod.predict.melt<-melt(mod.predict.sub, id.vars=c("PointID","Predicted","SE","lower","upper"), measure.vars=c("Elevation_m","Closed.tree.canopy","Herbaceous.grassland","Herbaceous.shrub.steppe","Open.tree.canopy","Open.Tree.Canopy","Shrubland","Sparse.tree.canopy","Sparsely.vegetated","Non.vegetated","No.Dominant.Lifeform"), variable.name = "Variable", value.name="value")
mod.predict.melt<-melt(mod.predict.sub, id.vars=c("PointID","Predicted","SE","lower","upper"), measure.vars=c("Herbaceous.grassland","Open.tree.canopy"), variable.name = "Variable", value.name="value")
#plot Abundance vs. Vegetation class proportions
abun.plot<-ggplot(data=mod.predict.melt, aes(x=value, y=Predicted))+
geom_point(aes(color=Variable),alpha=0.1,size=1)+
geom_smooth(method = "glm", formula = y~x, method.args = list(family = poisson(link = 'log')), aes(color=Variable, fill=Variable),alpha=0.2,fullrange=FALSE)+
# scale_color_manual(values=myColors)+
# scale_fill_manual(values=myColors)+
theme(
panel.background = element_rect(fill="white",color="black"),
panel.border = element_rect(fill="transparent",color="black"),
axis.text.x = element_text(size=8),
axis.text.y = element_text(size=8),
legend.position="bottom"
)+
labs(x="Abundance Covariate", y="Predicted relative abundance")
#facet over Vegetation_class
abun.plot.facet<-abun.plot+facet_wrap(Variable~.,scales="free",ncol=4)
abun.plot.facet
#create filename with timestamp
new.filename<-paste("Fig_11_Predicted_Abundance_models_with_veg_class",".png",sep="")
ggsave(abun.plot.facet, file=paste("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/",new.filename, sep=""),width=8, height=8, dpi=600)
#load predictive surface
pred_surface<-read.csv("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Data/ALL_covs_pred_surface.csv")
# #remove unwanted columns
#pred_surface$Dwarf.shrubland<-NULL
# pred_surface$Herbaceous.shrub.steppe<-NULL
# pred_surface$No.Dominant.Lifeform<-NULL
# pred_surface$Non.vegetated<-NULL
# pred_surface$Shrubland<-NULL
# pred_surface$Sparse.tree.canopy<-NULL
# pred_surface$Elevation_m<-NULL
#pred_surface$Sparsely.vegetated<-NULL
#get predicted estimates of avian occupancy as a function of vegetation cover on map
abun_pred <- predict(mod.global,
newdata = as.data.frame(pred_surface),
type = "state", appendData=TRUE)
#replace any estimates > max predicted value from model with max
# range(abun_pred$Predicted)
# range(abun_pred$SE)
# max.mod.value<-max(mod.predict.sub$Predicted)
#
# abun_pred$Predicted<-ifelse(abun_pred$Predicted>max.mod.value, max.mod.value, abun_pred$Predicted)
suppressMessages({
# add to prediction surface
pred_abun <- bind_cols(pred_surface,
abun_estimate = abun_pred$Predicted,
abun_se = abun_pred$SE) %>%
select(Latitude, Longitude, abun_estimate, abun_se)
})
#melt to plot in ggplot
pred_abun.melt<-melt(pred_abun, id.vars=c("Latitude","Longitude"),
variable.name = "Measure",value.name="Relative_abundance")
map.abun.plot<-ggmap(basemap,darken = c(0.4, "black"))+
geom_tile(data=pred_abun.melt, aes(x=Longitude, y=Latitude, fill=`Relative_abundance`,color=`Relative_abundance`))+
geom_map(data=states.poly, map=states.poly, aes(y=lat, x=long, map_id=id),color=alpha("white",0.3),fill="transparent", inherit.aes = FALSE,size=0.1)+
scale_fill_gradientn(colors=viridis(100),na.value = "transparent")+
scale_color_gradientn(colors=viridis(100),na.value = "transparent")+
labs(x="Longitude",y="Latitude")+
theme(axis.text=element_text(size=12),
axis.title=element_text(size=14),
axis.text.x=element_text(size=8),
axis.text.y=element_text(size=8),
panel.border=element_rect(fill="transparent", color="black"),
legend.position = "right")+
ggtitle(paste("WPWI"," - Estimated relative abundance",sep=""))+
#geom_text_repel(check_overlap = FALSE, size=3, nudge.y=-10, nudge.x=-10,aes(x=Longitude, y=Latitude,color=PatchID, label=PatchID),data=PatchID_labels)+
#guides(fill = guide_legend(title = "National Wildlife Refuge", label = FALSE))+
ggsn::scalebar(x.min=mapExtent$ll.lon, x.max=mapExtent$ur.lon, y.min=mapExtent$ll.lat, y.max=mapExtent$ur.lat,transform=TRUE, dist_unit="km",dist=100, st.dist=0.03, height = 0.015, anchor=c(x=-70.5,y=38.55), border.size=0.5,st.size=3)
map.abun.plot.facet.save<-map.abun.plot+facet_wrap(Measure~., ncol=1)
#create filename with timestamp
new.filename<-paste(paste("Fig_12_WPWI_","Map_Predicted_relative_abundance",sep=""),".png",sep="")
ggsave(map.abun.plot.facet.save, file=paste("/Users/zach/Dropbox (ZachTeam)/Projects/USFWS_WPWI/Results/Figures/",new.filename, sep=""),width=14, height=8, dpi=600)
print(map.abun.plot.facet.save)