Subset polygons in R

I am trying to separate a specific area on my window of analysis. I have a georeferenced floor plan with rooms as polygons. I want to select and plot only some the rooms

I tried this:

``````rooms <- readOGR (dsn="shp", layer="rooms")
rooms = cbind(rooms, roomattr)
rcluster = rooms[rooms\$rooms.Rooms=="R81", rooms\$rooms.Rooms=="R82", rooms\$rooms.Rooms=="R84"]
rcluster <- as(rcluster,"owin")
plot (rcluster)
``````

But I got only the first room plotted (R81). I also tried to put "&" between "rooms\$rooms.Rooms=="R..."" instead of a ",", but I only got error messages

Moreover I tried

``````rcluster <- rooms[rooms\$rooms.Rooms %in% paste0("R89", "R90", "R91", "R92")]
rcluster<-as(rcluster,"owin")
plot(rcluster)
``````

This just gave me the whole floor plan

Any idea?

You can find my shp and csv file here

– PolyGeo
Oct 17 at 8:36

I think the easiest approach you could take would be to perform a spatial join from the points to the polygons.

We can accomplish the join using `sf`, the data manipulation with `dplyr`, and the visualization with `ggplot2`.

Note that when we read in the csv file we're also piping it (sending the results forward) to the `st_as_sf()` function and we're specifying the columns that contain the x and y coordinates. Further, we specify the crs to be the same as the `room_sf` object which is needed for the spatial join—that way we can reference them accordingly in space.

``````library(sf)
library(dplyr)
library(ggplot2)

# read the csv and cast to sf object setting crs to the same as room_sf
st_as_sf(coords = c("XCoord", "YCoord"),
crs = st_crs(room_sf))
``````

Quickly we can visualize these together and we see that the points fall inside of the polygons quite nicely.

``````plot(st_geometry(room_df))
``````

Here we join them together using `sf::st_join()`. By default it joins the data from the second argument to the data in the first argument (retaining the geometry from the first).

``````# join them together
rooms <- st_join(room_sf, room_df)
``````

Now with this data you can subset it and visualize it with ggplot2. This first plot subsets to the three rooms you were interested in and fills the polygons based on the value of `Rooms_csv.Bench`. If you dont want to fill you can delete `aes(fill = Rooms_csv.Bench)`.

``````# subset and visualize a few rooms
rooms |>
filter(rooms.Rooms %in% c("R81", "R82", "R84")) |>
# select an attribute to visualize
ggplot(aes(fill = Rooms_csv.Bench)) +
geom_sf()
``````

This second plot visualizes all of the rooms and fills based on the bench presnce.

``````# Visualize just a single attribute for all rooms
rooms |>
# select an attribute to visualize
ggplot(aes(fill = Rooms_csv.Bench)) +
geom_sf()
``````

Created on 2022-09-23 by the reprex package (v2.0.1)

If I understand correctly your question, you to plot your shapefile based on a specific value/column from the attribute table. If that's the case then:

``````   library(sf)

rooms = seq(1:84)
d['rooms'] <- rooms

# write.csv(Your DataFrame,"Path to export the DataFrame\\File Name.csv", row.names = FALSE)

# create a new column called "rooms" in the shp
nc\$rooms<-1:nrow(nc)

# merge on common variable, here called 'rooms'
m <- merge(nc, d, by = 'rooms')

# maybe save your new shp using writeOGR function?
# writeOGR(obj, dsn, layer, driver)

# plot the whole shp
plot(m)

# plot specific column
plot(m['Rooms_csv.Bench'])

# plot rows 2 to 9 of each attribute
plot(m[2:9,])

# plot the 'Yes' attribute of the Rooms_csv.Bench column
plot(m[m\$Rooms_csv.Bench == 'Yes', 'Rooms_csv.Bench'])

plot(m[m\$Rooms_csv.Slab == 'No', 'Rooms_csv.Slab'])

# plot the 'Yes' attribute of the Rooms_csv.Bench column on one plot and the 'No' attribute from the Rooms_csv.Slab column next to it
par(mfrow=c(1,2))
plot(st_geometry(m[m\$Rooms_csv.Bench == 'Yes', 'Rooms_csv.Bench']))
plot(st_geometry(m[m\$Rooms_csv.Slab == 'No', 'Rooms_csv.Slab']))

# plot rooms R89, R90, R91
par(mfrow=c(1, 3))
plot(st_geometry(m[m\$Rooms == 'R89', 'Rooms']))
plot(st_geometry(m[m\$Rooms == 'R90', 'Rooms']))
plot(st_geometry(m[m\$Rooms == 'R91', 'Rooms']))
``````
• More or less. What I want to do is to subset it according to room ID. Eg I want to plot only rooms R89, R90, R91, not only one of those Sep 23 at 10:03
• I edited my answer and I included a side-by-side plot for the specific rooms. Now, if you want to make the plot more aesthetically pleasant I recommend to have a look at the `ggplot2` package. Sep 23 at 11:15
• Your example is reading in an sf class object with `sf::st_read` so, `rgdal::writeOGR` will not work without first coercing into an sp class ie., `as(x, "Spatial")`. You can subset on the fly using something like `plot(st_geometry(m[which( m\$Room %in% ('R89','R90', 'R91')),]))` Sep 23 at 12:05
• @JeffreyEvans yes that's a better approach indeed. Sep 23 at 12:39