I'd like to calculate the centroid of each cluster (in my example I considering points in < 10m distance to the same cluster) of points using mean operation (spdplyr package) for coordinates and another operation (sum) for the attribute(area) without success.
In my example:
#Packages
library(sp)
library(maptools)
library(spdplyr)
library(cluster)
# Small sample (40 points)
small.sample<-read.csv("https://raw.githubusercontent.com/Leprechault/trash/main/sample_points.csv")
#Convert to spatial object
xy.small.sample <- small.sample[,c(1,2)]
spdf.small.sample <- SpatialPointsDataFrame(coords = xy.small.sample, data = small.sample,
proj4string = CRS("+proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0"))
# Transform to UTM
utm.wgs.84 <- "+proj=utm +zone=21 +south +datum=WGS84 +units=m +no_defs"
small.sample.utm <- spTransform(spdf.small.sample, utm.wgs.84)
#
#Convert each cluster to one point
Rc=10 #Maximum distance between points - 10 meters
small.sample.utm.dm<-spDists(small.sample.utm) # Matrix distance
clusters <- as.hclust(agnes(small.sample.utm.dm, diss = T)) #Hierarchical Clustering
small.sample.utm#data$class<- cutree(clusters, h=Rc) # Cut into Groups 4.36 meters
# Average of x and y coordinates and area using spdplyr package
small.sample.utm.classification<- small.sample.utm %>%
group_by (class) %>%
summarise (area_clu=mean(area),x_clu=mean(coords[,1]),y_clu=mean(coords[,2]))
#Erro: Problem with `summarise()` input `x_clu`.
#x objeto 'coords' não encontrado
#i Input `x_clu` is `mean(coords[, 1])`.
#i The error occurred in group 1: class = 1.
My goal is:
# Original points representation
plot(small.sample.utm, pch=16)
# Cluster centroids representation
points(small.sample.utm.classification$x_clu,small.sample.utm.classification$y_clu, col="red")
# Labelling the area
text(small.sample.utm.classification$x_clu ~ small.sample.utm.classification$x_clu, labels=small.sample.utm.classification$area_clu, cex=0.9, font=2)
Related
I have a point vector for the entire globe at 0.25 degree resolution.
library(terra)
library(rnaturalearth)
# create point data
ref_grid <- terra::ext(-180, 180, -90, 90)
ref_grid <- terra::rast(ref_grid)
res(ref_grid)<- 0.25
values(ref_grid)<-1 #dummy values
projections <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
crs(ref_grid) <- projections
pts <- terra::as.points(ref_grid, values=TRUE, na.rm=TRUE)
# download world shapefile
world_shp <- rnaturalearth::ne_countries()
world_shp <- terra::vect(world_shp)
world_shp <- terra::project(world_shp, projections)
I want to extract those points that fall within a landmass i.e. remove all those points that are in the ocean. So I did this:
e <- terra::extract(world_shp, pts)
But it's been two hours now and this is still running. Is there any faster way to do this?
You should not transform raster data to vector data if you want efficiency. In this case, you can do the following in a second or so:
library(terra)
library(rnaturalearth)
ref_grid <- terra::rast(res=0.25)
world_shp <- rnaturalearth::ne_countries(returnclass="sf") |> vect()
ref_grid <- rasterize(world_shp, ref_grid)
p <- as.points(ref_grid)
(but perhaps, depending on what you do next, the last step should also be avoided)
I have a raster, and want to only retain the sea part of the raster, and remove the land part or the raster. If my raster is "ras" and my SpatialpolygonDataFRame is "worldMap", I tried
ras.msk <- rgeos::gDifference(ras,worldMap)
however, I get the following error which I do not understand, but I gather that the function can only be used with two spdf's, not with a raster?
Error in RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") : rgeos_convert_R2geos: invalid R class RasterLayer, unable to convert.
if I do
r2 <- crop(ras, worldMap)
r3 <- mask(r2, worldMap)
I get the land-part of the raster. How do I get the opposite so that the remaining raster excludes the overlapping spatialpolygondataframe area?
The end result I need is all raster point values at sea to be 1, and the raster point values on land to be 0.
My current code is as follows:
# Make raster layer of study area
ras = raster(ext=extent(-70, -55, -60, -38), res=c(0.01,0.01)) #lat/long xmin, xmax, ymin, ymax #
#give all raster points a "1"
ras[] <- 1
#project the raster
projection(ras) <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
# load land
library(rworldmap)
worldMap <- getMap(resolution = "high")
projection(worldMap) <- CRS(proj4string(ras))
#crop raster by land
ras.msk <- rgeos::gDifference(ras,worldMap)
Need to specify "inverse = T" in the mask function
r2 <- crop(ras, worldMap)
r3 <- mask(r2, worldMap, inverse = T)
I've got a map with certain number of points on it. I want to (1) calculate the number of points that fall within the raster layer, and (2) extract these points to a data frame.
This is what I've done:
# Packages
library(raster)
library(ggplot2)
library(maptools)
library(tidyverse)
library(dplyr)
library(sp)
# Transform tree ring kml to dataframe
zz<-getKMLcoordinates('treering.kml', ignoreAltitude=TRUE)
l<-as.data.frame(zz)
l<-t(l)
tree <-SpatialPointsDataFrame(l, l,
proj4string = CRS(" +proj=longlat +ellps=WGS84 +datum=WGS84
+no_defs +towgs84=0,0,0"))
# Get world map
data(wrld_simpl)
# Transform World to raster
r <- raster(wrld_simpl, res = 1)
wrld_r <- rasterize(wrld_simpl, r)
# Import permafrost layer to raster
dist1<-raster("PZI.flt")
# Set CRS
dist1 <- projectRaster(from = dist1, crs = CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs
+towgs84=0,0,0"))
# Change colours
micolor <- rev(rainbow(12, alpha = 0.35))
transp <- rainbow(12, alpha = 0)
micolor[1:3] <- transp[1]
# Plot all
plot(wrld_r, col = "lightgrey")
plot(dist1, add=TRUE, legend = F, col = micolor)
plot(tree, add=T, pch = 20, col='black', cex=0.2)
I want to calculate and extract black points located on the colorful parts of this map
First raster::projectRaster does not "set" the projection but, rather reprojects the raster given a transformation and resampling. Given the computational requirements of this it is much faster to reproject the point data using sp::spTransform. Once your data is in the same projection space, you can use raster::extract to extract the raster values. Values out side the raster or in nodata (NA) areas will be assigned NA values. You can drop these observations using a simple NA index with which.
It looks like your data may have a constant value outside of the permafrost. Once you identify what this value is (eg., 0) you can remove these points as well. Here is a worked example. First we add packages and create some example data that is similar to yours.
library(sp)
library(raster)
dist1 <- raster(nrow=20, ncol=20)
dist1[] <- sample(1:10, ncell(dist1), replace=TRUE)
dist1[200:400] <- 0
trees <- sampleRandom(dist1, 100, sp=TRUE)
plot(dist1)
plot(trees,pch=20,col="red",add=TRUE)
Now, we extract the raster values and look at the dimensions of the point object (please note that I do not have to use the sp=TRUE argument in the raster::extract function).
trees#data <- data.frame(trees#data, dist1 = extract(dist1, trees))
dim(trees)
Now we create a row index indicating which rows contain zeros, make sure that we have identified rows (using an if statement) and then remove them. Looking at the object dimensions again, we can see how many points were removed from the original point data.
( idx <- which(trees$dist1 %in% 0) )
if(length(idx) > 0) trees <- trees[-idx,]
dim(trees)
I have a grid of the map of Porto, I would like to be able to insert in the grid the points to discretize them. In this way to see how many points are in each cell depending on the time.
This is the code of the grid:
#latitudS and longitudS are coordinates x Y
x = longitudS
y = latitudS
df = data.frame(x, y)
# Converting to a Spatial Points Data Frame so you can keep the value that you will change within the Grid
points = SpatialPointsDataFrame(coords = df[, 1:2], df)
# load some spatial data. Administrative Boundary
porto <- getData('GADM', country = 'Portugal', level = 2)
porto$NAME_1
porto <- porto[porto$NAME_2 == "Porto",]
# check the CRS to know which map units are used
proj4string(porto)
# "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
# Create a grid of points within the bbox of the SpatialPolygonsDataFrame
# colorado with decimal degrees as map units
grid <- makegrid(porto, cellsize = 0.003) # cellsize in map units!
# grid is a data.frame. To change it to a spatial data set we have to
grid <- SpatialPoints(grid, proj4string = CRS(proj4string(porto)))
portoWithin <-
SpatialPixels(grid, proj4string = CRS(proj4string(porto)))
#### Converting the GRID to a Raster
ras_portoWithin <- raster(portoWithin)
## Assigning temporary values to the raster
values(ras_portoWithin) <- 0
## Using the Spatial point file created above to replace the values of the raster
r1 <- ras_portoWithin
plot(porto)
plot(portoWithin, add = T)
The idea is that for each cell the number of points will be output depending on the time in which the points have been recorded.
Also ask if there would be any way to transfer that grid to a leaflet, so you can see it on a map.
Thanks!
I have a dataset with points with x y coordinate, I want to create a grid, and insert this points into de the grid, to visualize better the information of the points.
I have create the grid (I am not sure if is the best way to do it):
# load some spatial data. Administrative Boundary
porto <- getData('GADM', country = 'Portugal', level = 2)
porto$NAME_1
porto <- porto[porto$NAME_2 == "Porto", ]
# check the CRS to know which map units are used
proj4string(porto)
# "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
# Create a grid of points within the bbox of the SpatialPolygonsDataFrame
# colorado with decimal degrees as map units
grid <- makegrid(porto, cellsize = 0.003) # cellsize in map units!
# grid is a data.frame. To change it to a spatial data set we have to
grid <- SpatialPoints(grid, proj4string = CRS(proj4string(porto)))
portoWithin <- SpatialPixels(grid, proj4string = CRS(proj4string(porto)))
plot(porto)
plot(portoWithin, add = T)
I would like to create a heat map with the grid to see in whith area concentrates more points.
Lets say your dataset with points with x y coordinate is this:
#### Data you have that will change the grid values #########
x = c(-8.64, -8.60, -8.65)
y = c(41.14, 41.16, 41.17)
val = c(21,10,30)
df =data.frame(x,y,val)
# Converting to a Spatial Points Data Frame so you can keep the value that you will change within the Grid
points = SpatialPointsDataFrame(coords = df[,1:2],df)
Now that you have your Spatial Point loaded in with the Values that will change your Grid. All you have to do is convert your grid to a Raster, Here is all of your code, with some of my work below it, with comments:
# load some spatial data. Administrative Boundary
porto <- getData('GADM', country = 'Portugal', level = 2)
porto$NAME_1
porto <- porto[porto$NAME_2 == "Porto", ]
# check the CRS to know which map units are used
proj4string(porto)
# "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
# Create a grid of points within the bbox of the SpatialPolygonsDataFrame
# colorado with decimal degrees as map units
grid <- makegrid(porto, cellsize = 0.003) # cellsize in map units!
# grid is a data.frame. To change it to a spatial data set we have to
grid <- SpatialPoints(grid, proj4string = CRS(proj4string(porto)))
portoWithin <- SpatialPixels(grid, proj4string = CRS(proj4string(porto)))
#### Converting the GRID to a Raster
ras_portoWithin <- raster(portoWithin)
## Assigning temporary values to the raster
values(ras_portoWithin) <- 0
## Using the Spatial point file created above (the one with your values) to replace the values of the raster
r1 <- ras_portoWithin
r1[points] <- points$val
plot(r1)
You now have your Grid, with the values given by your points!
Let me know if this helps!