How to fix error in non-numeric matrix in R - r

I have this data frame:
structure(list(Nazwa = c("a", "b"), Miejscowosc = c("aaa", "bbb"
), KodPocztowy = c("09-520", "44-207"), Zainstalowano = c("2020-03-20 00:00:00.000",
"2019-02-27 00:00:00.000"), Szczytowa = c(9.14, 4.5), Latitude = c("52.550000",
"50.101860"), Longitude = c("19.700000", "18.546640")), row.names = c(NA,
-2L), class = c("tbl_df", "tbl", "data.frame"))
I read this data from the aaa.xlsx file.
points <- read_xlsx(paste0("From/",qwerty,"/aaa.xlsx"))
Then I try to use the code:
points_sp <- SpatialPoints(points[,c(6,7)], CRS("+init=EPSG:4326"))
Unfortunately I am getting an error:
cannot derive coordinates from non-numeric matrix
How to solve it?

You just need to convert the character strings to numeric and the tbl_df to a matrix or plain data frame:
points$Latitude <- as.numeric(points$Latitude)
points$Longitude <- as.numeric(points$Longitude)
points_sp <- SpatialPoints(as.data.frame(points[,c(6,7)]), CRS("+init=EPSG:4326"))
points_sp
SpatialPoints:
# Latitude Longitude
# [1,] 52.55000 19.70000
# [2,] 50.10186 18.54664
# Coordinate Reference System (CRS) arguments: +proj=longlat +datum=WGS84 +no_defs

Related

Can I join two datasets by coordinates categories in different EPSGs?

Thanks for taking your time to read this
I am trying to join two different datasets where the only common possible columns are coordinates. However, one of those datasets uses a normal system of coordinates (e.g. lat=39.35678, long=-8.99740) while the other uses EPSG 25830 (e.g. x=236044.949, y=4141285.671). I am quite new to R and spacial data so I don't quite get the documentation on spTransform, but I really need to join those two datasets and the coordinates are the only common variable i can use. I've been trying to transform the columns on data_1 with EPSG:25830 to EPSG:4326 (the one data_2 uses).
Here's an example of what I mean (and how I've been trying to solve it)
Here's the first dataset, with the EPSG:25830
structure(list(TOTAL_PLAZAS = c(4, 8, 6, 4, 6, 6), X = c("234755.4852",
"235629.3447", "235170.6602", "235074.569", "235480.4626", "239104.22"
), Y = c("4143050.4408", "4142032.4727", "4142819.3263", "4142736.735",
"4142705.8228", "4140674.42"), SRID = c("25830", "25830", "25830",
"25830", "25830", "25830")), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
And here's the other dataframe, with the usual coordinates
structure(list(accommodates = c(4L, 3L, 2L, 6L, 6L, 4L), longitude = c(-5.99975,
-5.99533, -5.98537, -5.99795, -5.99379, -5.99497), latitude = c(37.39358,
37.39898, 37.38816, 37.39794, 37.39941, 37.38551)), class = c("rowwise_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list(
.rows = structure(list(1L, 2L, 3L, 4L, 5L, 6L), ptype = integer(0), class = c("vctrs_list_of",
"vctrs_vctr", "list"))), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame")))
This is what I've been trying, but so far it only transforms the original dataframe into a spatial points data frame, which is no use for me since i just need the original dataset with converted coordinates in order to join it with the other dataset.
coordinates(data_1) <- c("X","Y")
proj4string(data_1) <- CRS("+init=epsg:25830")
CRS.new <- CRS("+init=epsg:4326")
dnew <- spTransform(data1, CRS.new)
Many thanks again!!
You can use the sf package to convert the data into spatial objects and do all the desired spatial operations. The only problem with your data is that the spatial point locations of both datasets do not intersect. Thus, if you do a spatial join with st_join, no join will actually occur. I think that you might be interested in using a buffer st_buffer to force an intersection between the two datasets.
# Create simple feature object from a simple table indicating X and Y coordinates, as well as its crs.
data1 <- data1 |>
st_as_sf(coords = c("X", "Y"),
crs = 25830) |>
# Then transform it to the desired crs.
st_transform(crs = 4326)
# Do the same for data2
data2 <- data2 |>
st_as_sf(coords = c("longitude", "latitude"),
crs = 4326)
# Check if data intersects
st_intersects(data1, data2)
# This returns a list with empty entries meaning that there is no intersection among any of the spatial objects contained in data1 and data2
# Do join by spatial coordinates
resul <- data1 |>
# Maybe you are interested in using a buffer to force an intersection between the two objects
st_buffer(dist = 200) |>
# Do spatial join
st_join(data2)
# Finally, you can plot the data to visualize the spatial intersections
library(tmap)
tm_shape(data1|>
st_buffer(dist = 200)) +
# plot data1 with buffer as green filled circles
tm_fill(col = "forestgreen") +
tm_shape(data2) +
# plot data2 as red dots
tm_dots(col = "firebrick2",
size = 0.3)

Error: Column named '1640233800' cannot be found in 'df'

I'm using R and moveVis package of R to do some movement visualization. Below is the csv from where I import the data using read.csv
I'm having trouble converting the data.frame to moveStack using df2move
trackId,x,y,time,x1,x2,optional,sensor,timestamps
A34,19.00094708496841,72.8264388198447,2021-12-23 10:00:00,19.00094708496841,72.8264388198447,FALSE,unknown,2021-12-23 10:00:00
A34,18.986663359819435,72.84012881354482,2021-12-23 10:02:00,18.986663359819435,72.84012881354482,FALSE,unknown,2021-12-23 10:02:00
raw_data <- read.csv("mdata2.csv", header = TRUE)
m <- df2move(raw_data, proj = "+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs", x = "x1", y = "x2", time = as.POSIXct(raw_data$timestamps, format = "%Y-%m-%d %H:%M:%S", tz = "UTC"), track_id = "trackId")
Getting this error on running above code
Error: Column named '1640233800' cannot be found in 'df'
The problem is with your time argument. The format of time in your dataset and the one you are specifying in your code do not match. That's why you are getting an error.
In case you are using excel, it formats timestamps to its own default. You'll need to change it first (if it's the case).
This is what it does:
So, please check the format in your csv and what you are specifying in your code. You can change the format in excel by selecting the timestamp values and pressing Ctrl + 1 key.
All you need is this:
raw_data$timestamps <- as.POSIXct(raw_data$timestamps, format = "%Y-%m-%d %H:%M", tz = "UTC")
m <- df2move(raw_data, proj = "+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs", x = "x1", y = "x2", time = "timestamps", track_id = "trackId")
You have to specify a "character" for time within the df2move-function. Therefore, you have to do the transformation before applying the function (as #Vishal A. suggested as well). However, the transformation to Timestamps of class POSIXct was not correct, so NAs were introduced. See the solution:
raw_data <- structure(list(trackId = c("vipin", "vipin"), x = c(72.8409492130316, 72.8363572715711), y = c(18.9968003664781, 18.9958569245008), time = c("2021-12-23 10:00:00", "2021-12-23 10:02:00"), x1 = c(72.8409492130316, 72.8363572715711), x2 = c(18.9968003664781, 18.9958569245008 ), optional = c(FALSE, FALSE), sensor = c("unknown", "unknown" ), timestamps = structure(c(NA_real_, NA_real_), class = c("POSIXct", "POSIXt"), tzone = "UTC")), row.names = c(NA, -2L), class = "data.frame")
raw_data$timestamps <- as.POSIXct(raw_data$time, format = "%Y-%m-%d %H:%M:%S", tz = "UTC")
m <- moveVis::df2move(raw_data, proj = "+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs", x = "x1", y = "x2", time = "timestamps", track_id = "trackId")

How to calculate KUD for home range analysis using the package adehabitatHR?

i am trying to calculate KUD 50% and 95% for my penguin tracking data but have run into an error. My aim is to calculate the home range densities and then export the data as a polygon.
library(adehabitatHR)
library(sp)
library(readxl)
library(rgdal)
HRtracks<- as.data.frame(read_excel("allinterpolatedtracks.xlsx"))
# assign the correct columns as coordinates
coordinates(HRtracks)<-c("x","y")
proj4string(HRtracks)<- CRS("+init=epsg:3857")
#convert the coordinates to utm format
tracks.utm<-spTransform(HRtracks, CRS("+proj=utm +zone=60 +datum=WGS84"))
Error occurs after running this part of the script, tracks.utm[,X] indicates the column the data is sorted by, which is by individual tripID so it should create a range for each separate track.
colkud<-kernelUD(tracks.utm[,3],h="href", grid=1000,same4all=T)
The error:
Error: Can't subset columns that don't exist.
x Location 3 doesn't exist.
i There are only 1 column.
I suspect i am missing something in my script, however i am not an experienced user as of yet so hoping to get some advice.
The data:
tracks.utm <- dput(new("SpatialPointsDataFrame", data = structure(list(TripID = c(1,
1, 1, 1, 1, 1)), row.names = c(NA, -6L), class = c("data.frame")),
coords.nrs = numeric(0), coords = structure(c(165846.488217799,
165846.488227808, 165846.488167749, 165846.488257839, 165846.488237819,
165846.488718291, -19995889.0262206, -19995889.0261311, -19995889.0262007,
-19995889.0261311, -19995889.0260814, -19995889.0254053), .Dim = c(6L,
2L), .Dimnames = list(NULL, c("x", "y"))), bbox = structure(c(165846.488167749,
-19995889.0262206, 165846.488718291, -19995889.0254053), .Dim = c(2L,
2L), .Dimnames = list(c("x", "y"), c("min", "max"))), proj4string = new("CRS",
projargs = "+proj=utm +zone=60 +datum=WGS84 +units=m +no_defs")))
Cheers
Based on dput, you only have one column in your data. It is good practice to examine your data! If you look at str(tracks.utm#data) the only column is TripID and you are attempting to specify the third column.
If you look at the functions help you will see the xy argument that you are passing specifies:
An object inheriting the class SpatialPoints containing the x and y
relocations of the animal. If xy inherits the class
SpatialPointsDataFrame, it should contain only one column (factor)
corresponding to the identity of the animals for each relocation.
This means that TripID should be the only column, be a factor and correspond to the individual animal id(s). Since it is expected that there is only a single column it does not need to be specified, only the sp object. However, apparently the need for a single column does not seem to be the case and you can have multiple columns but need to specify the column containing the unique animal ids, thus the column bracket index.
To ensure that your animal ids are a factor (per help), I would recommend coercing the appropriate column (eg., TripID) to a factor.
library(sp)
library(adehabitatHR)
tracks.utm <- dput(new("SpatialPointsDataFrame", data = structure(list(TripID = c(1,
1, 1, 1, 1, 1)), row.names = c(NA, -6L), class = c("data.frame")),
coords.nrs = numeric(0), coords = structure(c(165846.488217799,
165846.488227808, 165846.488167749, 165846.488257839, 165846.488237819,
165846.488718291, -19995889.0262206, -19995889.0261311, -19995889.0262007,
-19995889.0261311, -19995889.0260814, -19995889.0254053), .Dim = c(6L,
2L), .Dimnames = list(NULL, c("x", "y"))), bbox = structure(c(165846.488167749,
-19995889.0262206, 165846.488718291, -19995889.0254053), .Dim = c(2L,
2L), .Dimnames = list(c("x", "y"), c("min", "max"))), proj4string = new("CRS",
projargs = "+proj=utm +zone=60 +datum=WGS84 +units=m +no_defs")))
tracks.utm#data$TripID <- factor(tracks.utm#data$TripID)
str(tracks.utm#data)
( colkud <- adehabitatHR::kernelUD(tracks.utm[,1], h="href",
grid=1000, same4all=TRUE) )
image(colkud)
points(tracks.utm, pch=20)

Joining seperate SpatialPolygons within a list in R

This is an example of a list with two separate (not adjacent or overlapping) SpatialPolygons and I would like to join them into one shapefile. For some reason no matter what I try I keep getting an error:
library(sp)
coords = matrix(c(78.46801, 19.53407,
78.46801, 19.74557,
78.83157, 19.74557,
78.83157, 19.53407,
78.46801, 19.53407),
ncol = 2, byrow = TRUE)
P1 = Polygon(coords)
Ps1 = SpatialPolygons(list(Polygons(list(P1), ID = "a")), proj4string=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"))
coords2 = matrix(c(77.46801, 17.53407,
77.46801, 17.74557,
77.83157, 17.74557,
77.83157, 17.53407,
77.46801, 17.53407),
ncol = 2, byrow = TRUE)
P2 = Polygon(coords2)
Ps2 = SpatialPolygons(list(Polygons(list(P2), ID = "a")), proj4string=CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"))
P_list <- list(Ps1,Ps2)
joined = SpatialPolygons(lapply(P_list, function(x){x#polygons[[1]]}))
Error in validObject(res) :
invalid class “SpatialPolygons” object: non-unique Polygons ID slot values

Overlaying (plotting) point data on raster layer

So I have the following script trying to prepare the data to do modelling on them later on using "biomod2" package. It tries to overlay species (xlm) presence points on environmental layers (bio1, bio7).
library(biomod2)
library(raster)
data <- structure(list(longitude = c(-122.84,-119.418,-78.6569,-78.1834, -89.3985), latitude = c(45.28,36.7783,37.4316,-1.8312, 32.3547)), .Names = c("X_WGS84",
"Y_WGS84"), class = "data.frame", row.names = c(NA, -5L))
data$xlm<-1
spdf <- SpatialPointsDataFrame(coords = xy, data = data,
proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
myRespName <- 'xlm'
myResp <- as.numeric(data[,myRespName])
myRespXY <- data[,c('X_WGS84','Y_WGS84')]
myExpl = stack( system.file( "external/bioclim/current/bio3.grd", package="biomod2"),
system.file( "external/bioclim/current/bio4.grd", package="biomod2"))
myBiomodData <- BIOMOD_FormatingData(resp.var = myResp,expl.var = myExpl,resp.xy = myRespXY,resp.name = myRespName)
plot(myBiomodData)
It works in this case, however, the issue is when I want to replace "bio4.grd" and "bio3.grd" layers in the package with my own data, it doesn't work. I have tried it as follow. First i thought it might be "asci" file format but even by converting them to "grd" still I don't get the points overlayed on layers stacked. It does overlay only one point in Southern USA (around Louisiana, Mississippi) though.
library(biomod2)
library(raster)
data <- structure(list(longitude = c(-122.84,-119.418,-78.6569,-78.1834, -89.3985), latitude = c(45.28,36.7783,37.4316,-1.8312, 32.3547)), .Names = c("X_WGS84",
"Y_WGS84"), class = "data.frame", row.names = c(NA, -5L))
data$xylella<-1
spdf <- SpatialPointsDataFrame(coords = xy, data = data,
proj4string = CRS("+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"))
myRespName <- 'xylella'
myResp <- as.numeric(data[,myRespName])
myRespXY <- data[,c('X_WGS84','Y_WGS84')]
bio2<-raster("C:\\Data\\BioClim_V2_MaxEnt\\wc2.0_bio_10m_02.asc")
crs(bio2) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
writeRaster(bio2, "C:\\Data\\BioClim_V2_MaxEnt\\bio2", overwrite=TRUE)
bio7<-raster("C:\\Data\\BioClim_V2_MaxEnt\\wc2.0_bio_10m_07.asc")
crs(bio7) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
writeRaster(bio7, "C:\\Data\\BioClim_V2_MaxEnt\\bio7", overwrite=TRUE)
myExpl = stack (bio2,bio7)
myBiomodData <- BIOMOD_FormatingData(resp.var = myResp,expl.var = myExpl,resp.xy = myRespXY,resp.name = myRespName)
plot(myBiomodData)
Any help highly appreciated. Many thanks.

Resources