Create SpatialPointsDataframe
It uses the row order to ensure the match between coordinates and the data. And, you can tell it what columns to use for lon/lat. Here's a few examples that hopefully make it a bit clearer:
library(sp)
dat_orig <- read.table(text=" a b c d e lat lng
12 f2 23 dd 2d 15.6 80.9
12 g5 99 NA hh 20.9 10.9
13 g4 12 aa 3r3 1.2 81.8", header=TRUE, stringsAsFactors=FALSE)
dat <- dat_orig
coordinates(dat) <- ~lng+lat
dat
## coordinates a b c d e
## 1 (80.9, 15.6) 12 f2 23 dd 2d
## 2 (10.9, 20.9) 12 g5 99 <NA> hh
## 3 (81.8, 1.2) 13 g4 12 aa 3r3
dat_1 <- dat_orig
colnames(dat_1) <- c(colnames(dat_1)[1:5], "steve", "larry")
coordinates(dat_1) <- ~larry+steve
dat_1
## coordinates a b c d e
## 1 (80.9, 15.6) 12 f2 23 dd 2d
## 2 (10.9, 20.9) 12 g5 99 <NA> hh
## 3 (81.8, 1.2) 13 g4 12 aa 3r3
dat_2 <- SpatialPointsDataFrame(dat_orig[,c("lng", "lat")], dat_orig[,1:5])
dat_2
## coordinates a b c d e
## 1 (80.9, 15.6) 12 f2 23 dd 2d
## 2 (10.9, 20.9) 12 g5 99 <NA> hh
## 3 (81.8, 1.2) 13 g4 12 aa 3r3
dat_3 <- dat_orig
colnames(dat_3) <- c(colnames(dat_3)[1:5], "steve", "larry")
dat_3 <- SpatialPointsDataFrame(dat_3[,c("larry", "steve")], dat_3[,1:5])
dat_3
## coordinates a b c d e
## 1 (80.9, 15.6) 12 f2 23 dd 2d
## 2 (10.9, 20.9) 12 g5 99 <NA> hh
## 3 (81.8, 1.2) 13 g4 12 aa 3r3
And, here's what coordinates<-
is doing under the covers:
setReplaceMethod("coordinates", signature(object = "data.frame", value = "ANY"),
function(object, value) {
coord.numbers = NULL
if (inherits(value, "formula")) {
cc = model.frame(value, object, na.action = na.fail) # retrieve coords
if (dim(cc)[2] == 2) {
nm = as.character(as.list(value)[[2]])[2:3]
coord.numbers = match(nm, names(object))
} else if (dim(cc)[2] == 3) {
nm = c(as.character(as.list((as.list(value)[[2]])[2])[[1]])[2:3],
as.character(as.list(value)[[2]])[3])
coord.numbers = match(nm, names(object))
} # else: give up.
} else if (is.character(value)) {
cc = object[, value] # retrieve coords
coord.numbers = match(value, names(object))
} else if (is.null(dim(value)) && length(value) > 1) { # coord.columns?
if (any(value != as.integer(value) || any(value < 1)))
stop("coordinate columns should be positive integers")
cc = object[, value] # retrieve coords
coord.numbers = value
} else # raw coordinates given; try transform them to matrix:
cc = coordinates(value)
if (any(is.na(cc)))
stop("coordinates are not allowed to contain missing values")
if (!is.null(coord.numbers)) {
object = object[ , -coord.numbers, drop = FALSE]
stripped = coord.numbers
# ... but as.data.frame(x) will merge them back in, so nothing gets lost.
if (ncol(object) == 0)
#stop("only coords columns present: use SpatialPoints to create a points object")
return(SpatialPoints(cc))
} else
stripped = numeric(0)
SpatialPointsDataFrame(coords = cc, data = object, coords.nrs = stripped,
match.ID = FALSE)
}
)
Which shows it's just doing the SpatialPointsDataFrame
idiom for you in a shorter call.
To make a SpatialPointsDataFrame
you need 3 components:
- coordinates
- data
proj4string
of the coordinates (AKA, coordinate reference system (CRS))
# load some example data
library(sp) # spatial library
data(meuse) # load built in dataset
# prepare coordinates, data, and proj4string
coords <- meuse[ , c("x", "y")] # coordinates
data <- meuse[ , 3:14] # data
crs <- CRS("+init=epsg:28992") # proj4string of coords
# make the SpatialPointsDataFrame object
spdf <- SpatialPointsDataFrame(coords = coords,
data = data,
proj4string = crs)
# check the object class
class(spdf)
[1] "SpatialPointsDataFrame"
attr(,"package")
[1] "sp"
# plot the copper column
spplot(spdf, "copper")