#' Assign observations to zone or area
#' person("Melanie", "Harsch", role = c("aut"))
#'
#' @param dat Main data frame containing data on hauls or trips. Table in
#' fishset_db database should contain the string `MainDataTable`.
#' @param gridfile Spatial data. Shape, json, and csv formats are supported.
#' @param hull.polygon T/F If TRUE, creates convex hull polygon. Use if spatial
#' data creating polygon are sparse or irregular.
#' @param lon.dat Column containing longitude data in main data frame.
#' @param lat.dat Column containing latitude data in main data frame.
#' @param lon.grid If gridfile is not shape or json file, specify column
#' containing longitude data in gridfile.
#' @param lat.grid If gridfile is not shape or json file, specify column
#' containing latitude data in gridfile.
#' @param categ Column in gridfile that identifies the individual areas or zones.
#' If gridfile is class sf, `categ` should be name of list containing
#' information on zones.
#' @param closest.pt TRUE/FALSE If true, zone ID identified as the closest
#' polygon to the point.
#' @importFrom sp CRS Polygons Polygon SpatialPolygons SpatialPolygonsDataFrame
#' coordinates
#' @importFrom rgeos gDistance
#' @importFrom grDevices chull
#' @importFrom raster projection
#' @details Assign each observation to zones defined by a spatial data
#' set.
#' Converts point data from gridfile into polygons and then finds which polygon
#' each observation in the main data frame is within. Use hull.polygon=T
#' if data is sparse or irregular.
#' @keywords zone, polygon
#' @return Main data frame with new assignment column labeled zoneID.
#' @export
assignment_column <- function(dat, gridfile, hull.polygon,
lon.dat, lat.dat, categ,
closest.pt, lon.grid,
lat.grid) {
library(sp)
dataset <- dat
dataset[[lat.dat]] <- as.numeric(as.vector(dataset[[lat.dat]]))
dataset[[lon.dat]] <- as.numeric(as.vector(dataset[[lon.dat]]))
# sort data
gridfile <- as.data.frame(gridfile)
gridfile <- gridfile[order(gridfile[, categ], gridfile[, lon.grid],
gridfile[, lat.grid]), ]
# Create spatial polygon dataframe from grid data make a list
map_list <- split(gridfile[, c(lon.grid, lat.grid, categ)], gridfile[[categ]])
# only want lon-lats in the list, not the names
map_list <- lapply(map_list, function(x) {
x[categ] <- NULL
x
})
if (hull.polygon == T) {
ps <- lapply(map_list, function(x) x[c(grDevices::chull(x),
grDevices::chull(x)[1]), ])
p1 <- lapply(seq_along(ps), function(i) sp::Polygons(list(
sp::Polygon(ps[[i]])), ID = names(map_list)[i]))
} else {
# add id variable
ps <- suppressWarnings(lapply(map_list, sp::Polygon))
p1 <- lapply(seq_along(ps), function(i) sp::Polygons(list(ps[[i]]),
ID = names(map_list)[i]))
}
my_spatial_polys <- sp::SpatialPolygons(p1, proj4string =
sp::CRS("+proj=longlat +datum=WGS84"))
# Change to spatial polygon dataframe
srdf <- sp::SpatialPolygonsDataFrame(my_spatial_polys,
data.frame(row.names = c(names(map_list)), ID = names(map_list)))
# Assign zone to data set based on lat and long
dat_sub <- dataset
# Assignment modified according
sp::coordinates(dat_sub) <- c(lon.dat, lat.dat)
# Set the projection of the SpatialPointsDataFrame using the projection
# of the shapefile
sp::proj4string(dat_sub) <- sp::CRS("+proj=longlat +datum=WGS84")
#proj4string(sodo)
# identify intersections of points in data set with polygons in grid file
pts <- sp::over(dat_sub, srdf, duplicate = F)
if (closest.pt == TRUE) {
closest <- data.frame(matrix(NA, nrow = length(which(
is.na(pts$ID) == TRUE)), ncol = 1))
for (i in 1:length(which(is.na(pts$ID) == TRUE))) {
closest[i, 1] <- names(which(rgeos::gDistance(
dat_sub[which(is.na(pts$ID) == TRUE), ][i, ],
as(srdf, "SpatialLines"), byid = TRUE)[, 1] ==
min(rgeos::gDistance(dat_sub[which(is.na(pts$ID) == TRUE), ][i, ],
as(srdf, "SpatialLines"), byid = TRUE))))
}
pts[which(is.na(pts$ID) == TRUE), ] <- closest
}
if (any(is.na(pts$ID))) {
drop.points <- dataset[is.na(pts$ID)==TRUE, c(lon.dat, lat.dat)]
warning("Zone ID not identified for at least one point. Consider plotting
points against before dropping points by assigning remove.na to TRUE or
assigning these points to closest zone by setting closest to TRUE.
Undefined points are recorded in the log file")
}
pts <- cbind(dataset, ZoneID=pts$ID)
pts <- as.data.frame(pts)
return(pts)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.