Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect outer rows in the dataset

Tags:

r

I have data set that contain positions of the objects:

so <- data.frame(x = rep(c(1:5), each = 5), y = rep(1:5, 5))
so1 <- so %>% mutate(x = x + 5, y = y +2)
so2 <- rbind(so, so1) %>% mutate(x = x + 13, y = y + 7)
so3 <- so2 %>% mutate(x = x + 10)
ggplot(aes(x = x, y = y), data = rbind(so, so1, so2, so3)) + geom_point()

What I want to know is if there is a method in R that can detect that the object is located in the outer row in the data set as I have to exclude such objects from the analysis. I want to exclude the objects in red as on the picture enter image description here

So far I used min, max and ifelse but this is tidious and I could not create something that could be generalised to the different data sets with different design of x and y. Is there any package that do the thing? or/and is it possible to solve such a problem?

like image 613
Mateusz1981 Avatar asked Aug 10 '26 09:08

Mateusz1981


1 Answers

You could perhaps use a "spatial" approach? Visualizing your data as a spatial object, your problem would become to remove the borders of your patches...

This can be done quite straightforwardly using the package raster: find the boundaries and mask your data accordingly.

library(dplyr)
library(raster)

# Your reproducible example
myDF = rbind(so,so1,so2,so3)
myDF$z = 1 # there may actually be more 'z' variables

# Rasterize your data
r = rasterFromXYZ(myDF) # if there are more vars, this will be a RasterBrick
par(mfrow=c(2,2))
plot(r, main='Original data')

# Here I artificially add 1 row above and down and 1 column left and right,
# This is a trick needed to make sure to also remove the cells that are
# located at the border of your raster with `boundaries` in the next step.
newextent = extent(r) + c(-res(r)[1], res(r)[1], -res(r)[2], res(r)[2] )
r = extend(r, newextent)
plot(r, main='Artificially extended')
plot(rasterToPoints(r, spatial=T), add=T, col='blue', pch=20, cex=0.3)

# Get the cells to remove, i.e. the boundaries
bounds = boundaries(r[[1]], asNA=T) #[[1]]: in case r is a RasterBrick
plot(bounds, main='Cells to remove (where 1)')
plot(rasterToPoints(bounds, spatial=T), add=T, col='red', pch=20, cex=0.3)

# Then mask your data (i.e. subset to remove boundaries)
subr = mask(r, bounds, maskvalue=1)
plot(subr, main='Resulting data')
plot(rasterToPoints(subr, spatial=T), add=T, col='blue', pch=20, cex=0.3)

# This is your new data (the added NA's are not translated so it's OK)
myDF2 = rasterToPoints(subr)

enter image description here

Would it help you?

like image 70
ztl Avatar answered Aug 13 '26 08:08

ztl