I have a dataframe df1
with 10 columns. Two of these columns are lng
and lat
.
I want to create a SpatialPointsDataframe
f
SpatialPointsDataFrame
you need 3 components: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")
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.