I am trying to find the area of each polygon in my sf
data.frame
that does not intersect all of the other polygons. I've developed a for loop to determine the non-intersected polygons and save them into a new data.frame
but that causes it to lose the sf
class. Is there a way to perform this in a way that the class is not lost and I can plot the results?
Some data:
library(sf)
set.seed(1234)
xcoord <- runif(10, min=0,max=10)
ycoord <- runif(10,min=0,max=10)
points <- data.frame(x=xcoord,y=ycoord)
pointssf <- st_as_sf(points,coords=c('x','y'),dim='XY')
#create buffers from points
buffer <- st_buffer(pointssf,2)
#My attempt
buffsarea <- st_area(buffer)
#initialize data.frame
intbuffs <- data.frame(matrix(ncol = ncol(buffer), nrow = nrow(buffer)))
for(i in 1:nrow(buffer)){
rem1 = buffer[i,1]
left1 = buffer[-i,1]
leftunion = st_union(left1)
ab = st_covered_by(rem1,leftunion,sparse=F)
if(ab[[1]]==F){
intbuffs[i,1]= st_difference(rem1,leftunion)
}
else{
intbuffs[i,1] = 0 #for cases where entire buffer intersects
}
}
t_area(intbuffs)
Error in UseMethod("st_area") : no applicable method for 'st_area' applied to an object of class "data.frame"
CodePudding user response:
data.frame
objects cannot contain sf
objects, so if you want to save sf
objects using a loop, you should instead use list
objects. In addition, you can use lapply
to calculate the area of the resulting sf
objects, and for objects without features set its area = 0 .
# Make list instead of data.frame so sf objects can be saved in each entry
intbuffs <- vector("list", nrow(buffer))
for(i in 1:nrow(buffer)){
rem1 = buffer[i,1]
left1 = buffer[-i,1]
leftunion = st_union(left1)
ab = st_covered_by(rem1,leftunion,sparse=F)
intbuffs[[i]]= st_difference(rem1,leftunion)
}
# plot results
plot(intbuffs[[2]])
# Calculate area
resul <- lapply(intbuffs, function(x){
# Check for sf with 0 features
ifelse(nrow(x) == 0, 0, st_area(x))
})
# Convert from list to vector
unlist(resul)