How to Convert Data Frame to Spatial Coordinates

How to Convert data frame to spatial coordinates

First, you take the columns of lon and lat and create an object for coord. Then, you subtract them from the original data frame and create a new object. You finally use SpatialPointsDataFrame() to create a SpatialPointsDataFrame. When you create a SpatialPointsDataFrame, you need to assign proj4string. Choose an appropriate one for you.

In your case, you do not have any other columns but lon and lat, the method won't work. I purposely left lon and lat @data.

DATA

mydf <- structure(list(longitude = c(128.6979, 153.0046, 104.3261, 124.9019, 
126.7328, 153.2439, 142.8673, 152.689), latitude = c(-7.4197,
-4.7089, -6.7541, 4.7817, 2.1643, -5.65, 23.3882, -5.571)), .Names = c("longitude",
"latitude"), class = "data.frame", row.names = c(NA, -8L))


### Get long and lat from your data.frame. Make sure that the order is in lon/lat.

xy <- mydf[,c(1,2)]

spdf <- SpatialPointsDataFrame(coords = xy, data = mydf,
proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))


#> str(spdf)
#Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
#..@ data :'data.frame': 8 obs. of 2 variables:
#.. ..$ longitude: num [1:8] 129 153 104 125 127 ...
#.. ..$ latitude : num [1:8] -7.42 -4.71 -6.75 4.78 2.16 ...
#..@ coords.nrs : num(0)
#..@ coords : num [1:8, 1:2] 129 153 104 125 127 ...
#.. ..- attr(*, "dimnames")=List of 2
#.. .. ..$ : NULL
#.. .. ..$ : chr [1:2] "longitude" "latitude"
#..@ bbox : num [1:2, 1:2] 104.33 -7.42 153.24 23.39
#.. ..- attr(*, "dimnames")=List of 2
#.. .. ..$ : chr [1:2] "longitude" "latitude"
#.. .. ..$ : chr [1:2] "min" "max"
#..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slot
#.. .. ..@ projargs: chr "+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"

Converting data.frame with coordinates variable into sf object with geometry

You can specify which columns are the coordinates:

df <- data.frame(v1 = c(320000, 600000),
g_lat = c(-34.23000, 16.10000),
g_long = c(19.42833, -22.80000))

df_coord <- st_as_sf(df, coords = c(2:3))

Converting a data frame to a spatial object

The library sf and its st_as_sf() is a way to convert your data.frame to a spatial object. crs refers to the datum and projection, which I just guessed assuming your lat/long are relative to the WGS84 datum. I believe the projection is what maps.google.com uses - web mercator auxiliary sphere.

library(sf)
turf_clean <- st_as_sf(region, coords = c("xcol", "ycol"), crs = 4326)

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.

How to convert a spatial dataframe back to normal dataframe?

as.data.frame() does just what you are looking for:

library(sp)
# Construct a SpatialPointsDataFrame
data(meuse)
xy <- meuse[1:2]
df <- meuse[-1:-2]
SPDF <- SpatialPointsDataFrame(coords=xy, data=df)

# And then convert it (back) to a data.frame
DF <- as.data.frame(SPDF)

How to change class from data frame to spatial polygon?


my data is just the same as the other post [...]
So anyone can help me to change classfrom data.frame to spatial
polygon?

library(sp)
sp <- SpatialPolygons(list(Polygons(list(Polygon(mydf[, -1])), ID=1)))
class(sp)
# [1] "SpatialPolygons"
# attr(,"package")
# [1] "sp"

or, if you want exchange to be the polygon identifier:

sp <- lapply(split(mydf[, -1], mydf[, 1]), Polygon)
sp <- SpatialPolygons(lapply(seq_along(sp), function(i) {
Polygons(list(sp[[i]]), ID = row.names(mydf[!duplicated(mydf[, 1]), ])[i] )
}))
# class(sp)
# [1] "SpatialPolygons"
# attr(,"package")
# [1] "sp"

Data:

mydf <- read.table(header=T, text="
exchange longitude latitude
AB 103.3281386 1.594218196
AB 103.3285929 1.593990735
AB 103.3312494 1.591424235
AB 103.3283736 1.594063254
AB 103.3536164 1.622771588
AB 103.3613242 1.627138676
AB 103.3560151 1.619455334
AB 103.3297071 1.593398614
AB 103.3269466 1.596574285
AB 103.3279517 1.593614052
AB 103.3281356 1.593848271
AB 103.3567136 1.620498495
AB 103.3668021 1.63456952
AB 103.359686 1.624821271
AB 103.3308963 1.585290892
AB 103.3319569 1.59104387
AB 103.3307149 1.592006748
AB 103.3283657 1.593675616
AB 103.3314873 1.591186363
AB 103.3319648 1.590585241
AB 103.3321508 1.590422594
AB 103.3318503 1.588685843
AB 103.3324507 1.594547225
AB 103.3442528 1.60909707
AB 103.3292733 1.593461728
AB 103.3288584 1.594312512
AB 103.329041 1.594135083
AB 103.3348961 1.59761749
AB 103.3500524 1.614224612")

Convert data frame to spatial lines data frame in R with x,y x,y coordintates

I believe what you want to end up with is a column in your data frame that for each row is a list (or data frame) with x.coord and y.coord columns. To achieve that, we can use unnest and nest from tidyr with dplyr:

library(dplyr)
library(tidyr)
result <- finalsub %>% mutate(coordinates = strsplit(coordinates,split=" ",fixed=TRUE)) %>%
unnest(coordinates) %>%
mutate(coordinates = strsplit(coordinates,split=",",fixed=TRUE),
x.coord = as.numeric(unlist(coordinates)[c(TRUE,FALSE)]),
y.coord = as.numeric(unlist(coordinates)[c(FALSE,TRUE)])) %>%
select(-coordinates) %>%
nest(x.coord,y.coord,.key=coordinates)

Notes:

  1. The first mutate splits the character vector in your coordinates column by " " to separate each coordinate x,y resulting in a list of these.
  2. unnest separates this list into rows.
  3. In the second mutate, we first split each coordinate x,y, this time by "," to separate each coordinate into x and y. Then we create separate x.coord and y.coord columns to hold these. Note the conversion to numeric here.
  4. Finally, we use nest to collect the x.coord and y.coord columns as a list under the column named coordinates. Note that we first have to remove the original coordinates column.

The result using your dput data, printing only the coordinates column:

print(result$coordinates)
##[[1]]
### A tibble: 284 x 2
## x.coord y.coord
## <dbl> <dbl>
##1 -1.294832 54.61024
##2 -1.294883 54.61008
##3 -1.294262 54.61002
##4 -1.294141 54.61001
##5 -1.293710 54.61004
##6 -1.293726 54.61014
##7 -1.293742 54.61025
##8 -1.293510 54.61026
##9 -1.293368 54.61026
##10 -1.292816 54.61019
### ... with 274 more rows
##
##[[2]]
### A tibble: 322 x 2
## x.coord y.coord
## <dbl> <dbl>
##1 -1.294832 54.61024
##2 -1.294883 54.61008
##3 -1.294262 54.61002
##4 -1.294141 54.61001
##5 -1.293710 54.61004
##6 -1.293726 54.61014
##7 -1.293742 54.61025
##8 -1.293510 54.61026
##9 -1.293368 54.61026
##10 -1.292816 54.61019
### ... with 312 more rows


Related Topics



Leave a reply



Submit