0

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")
roomattr <- read.csv (file="rooms.csv", header=TRUE)
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

1
  • If you have a follow up question please ask that as a new question. To thank answers please upvote or accept answer(s).
    – PolyGeo
    Oct 17 at 8:36

2 Answers 2

4

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.

By loading the requisite libraries and reading in the data.

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 in the shapefile
room_sf <- read_sf("rooms.shp")

# read the csv and cast to sf object setting crs to the same as room_sf
room_df <- readr::read_csv("rooms.csv") |>
  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))
plot(st_geometry(room_sf), add = TRUE)

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)

0
0

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)
    
    # read data    
    nc <- st_read("path/rooms.shp")
    
    d <- read.csv("path/rooms.csv")
    
    rooms = seq(1:84)
    d['rooms'] <- rooms
    
    # export your csv
    # 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']))
4
  • 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
    – MaryM
    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.
    – Nikos
    Sep 23 at 11:15
  • 1
    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.
    – Nikos
    Sep 23 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.