20

I have a dataframe df1 with 10 columns. Two of these columns are lng and lat. I want to create a SpatialPointsDataframe from df1. When I read on how to create a SpatialPointsDataframe it feels like I have to create a matrix m1 from my two coordinates columns and then assign that matrix to the dataframe df1.

That would be a detour since my coordinates are already a column in my dataframe df1. Furthermore, how do I assure that the coordinates from my matrix m1 are assign to the correct rows in my dataframe df1?

thats how my df1 would look like

> df1
    a    b    c    d    e    lat   lng
1   12   f2   23   dd   2d   15.6  80.9
2   12   g5   99   NA   hh   20.9  10.9
3   13   g4   12   aa   3r3  1.2   81.8
4   ..   ..   ..   ..   ..   ..    .. 
5
  • dput(df1) wld be helpful Commented Sep 15, 2015 at 11:22
  • @hrbrmstr what would you need that for? I am asking a question related to the process of the creation of a spatial data frame. Commented Sep 15, 2015 at 11:32
  • 4
    @Chrissl Just use coordinates(df1) <- ~ lng + lat; this casts the data frame to an SpatialPointsDataFrame Commented Sep 15, 2015 at 11:36
  • @rcs thats exactly what I wonder. Where do I define lng + lat?! Do I need to extract them from df1 like lng <- df1$lng and lat <- df1$lat. If so, how does coordinates know which coordinates assign to which row. Does it do that by order, by a key? Or do I need to do something like coordinates(df1) <- ~ df1$lng + df1$lat Commented Sep 15, 2015 at 11:42
  • 1
    @Chrissl your "wonder" is exactly why having data to show a minimal example would be helpful vs an extended discussion in the comments or asking others to make data up to show you. Commented Sep 15, 2015 at 11:53

2 Answers 2

21

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Sweet. Thanks. I did not know that it does all of that automatically. I thought I need to tell it somewhere more on "how to match".
17

To make a SpatialPointsDataFrame you need 3 components:

  1. coordinates
  2. data
  3. 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")

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.