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:
- The first
mutate
splits the character vector in yourcoordinates
column by" "
to separate each coordinatex,y
resulting in alist
of these. unnest
separates this list into rows.- In the second
mutate
, we first split each coordinatex,y
, this time by","
to separate each coordinate intox
andy
. Then we create separatex.coord
andy.coord
columns to hold these. Note the conversion to numeric here. - Finally, we use
nest
to collect thex.coord
andy.coord
columns as a list under the column namedcoordinates
. Note that we first have to remove the originalcoordinates
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
Convert a Dataframe to a Vector (By Rows)
Insert a Logo in Upper Right Corner of R Markdown PDF Document
Dplyr - Using Mutate() Like Rowmeans()
What Does "Error: Object '<Myvariable>' Not Found" Mean
Ggplot2, Axis Not Showing After Using Theme(Axis.Line=Element_Line())
Group by and Filter Data Management Using Dplyr
Create Counter of Consecutive Runs of a Certain Value
R Matrix to Rownames Colnames Values
Writing Robust R Code: Namespaces, Masking and Using the '::' Operator
Can Sweave Produce Many PDFs Automatically
How to Delete Rows from a Data.Frame, Based on an External List, Using R
Is There a Weighted.Median() Function
Reason Behind Speed of Fread in Data.Table Package in R
How to Apply Cross-Hatching to a Polygon Using the Grid Graphical System
Adding New Column with Diff() Function When There Is One Less Row in R
Calling an R Function Using Inline and Rcpp Is Still Just as Slow as Original R Code