I downloaded two separate, similar but distinct shape files. They can be found here and here. The first file has filename "FED_A_FINAL_REPORT_BC.shp" and the second has filename "lfed000b21a_e". Using Shiny, I am able to place markers on one map (the second) but not the other(the first), and this is where I have my problem.
I have been able to reproduce this without adding any external data, in fact.
Once downloaded, you can read in the shape files as below:
new_bc_fed = sf::st_read("/Downloads/shapefile_folder_feds_canada/lfed000b21a_e.shp")
bc_fed_nova = sf::st_read("/Downloads/FED_A_FINAL_REPORT_BC.shp")
I am particularly interested in being able to use the first file, bc_fed_nova
, which is the one which does not work.
I then define a centroid for each of the polygons (federal electoral districts) within each of the two maps in exactly the same way:
bc_centroids = data.frame(st_coordinates(st_centroid(bc_fed_nova$geometry)))
bc_fed_nova$X = bc_centroids[,1]
bc_fed_nova$Y = bc_centroids[,2]
...and also:
bc_centroids = data.frame(st_coordinates(st_centroid(new_bc_fed$geometry)))
new_bc_fed$X = bc_centroids[,1]
new_bc_fed$Y = bc_centroids[,2]
Up to this point, everything I did was the same for both maps. I also checked that they are the same class of object:
> class(new_bc_fed_C)
[1] "sf" "data.frame"
> class(bc_fed_nova)
[1] "sf" "data.frame"
For the map called "bc_fed_nova," I added some data from a data frame which contains some census data (basically, I want to modify this to be able to show the population of each FED). This is how I did that:
census_data_file = ("/Downloads/98-401-X2021029_English_CSV_data.csv")
#Starting on line 807719
#Ending on line 923482
#We found this from the associated metadata, we want to
starting_line = 807719
ending_line = 923482
number_of_rows = ending_line - starting_line
census_data_BC = read.csv(census_data_file, nrows = number_of_rows, skip = (starting_line - 1), header = FALSE)
census_metadata = read.csv(census_data_file, nrows = 1)
#Remove the white space
census_data_BC_copy = census_data_BC
for(j in 1:ncol(census_data_BC_copy))
{
census_data_BC_copy[,j] = str_remove_all(census_data_BC_copy[,j], " ")
}
#Assign this column name so that we can merge with the DF in the map
#file
colnames(census_data_BC_copy)[5] = "FED"
#Find total population in each FED
totalpop_in_bc_feds = census_data_BC_copy[which(census_data_BC_copy$V10 == "Population,2021"),]
#We only need the following columns
totalpop_in_bc_cropped = totalpop_in_bc_feds[,c(2, 5, 12, 13, 14, 15)]
colnames(totalpop_in_bc_cropped)[3] = "TotalPop"
#To avoid double counting, remove the first row
totalpop_in_bc_cropped = totalpop_in_bc_cropped[-1,]
#Make sure that the column name has an equivalent in the target
# sf object
colnames(new_bc_fed)[4] = "FED"
#The original name was "FEDENAME"
#We merge this data with the sf/dataframe from above
bc_fed_nova = dplyr::left_join(bc_fed_nova, totalpop_in_bc_cropped, by = "FED")
#Confirm that the data has been merged with the data frame from the map
What I want is to use these maps as the basis for a Shiny app in R which does something very simple: as you move around, you should see markers on the centroid of a district and to be able to see the surface area of the federal electoral district when clicking on the marker. I did this code twice, but only one version of the code works:
library(shiny)
library(WikidataQueryServiceR)
library(leaflet)
ui <- fluidPage(
# Application title
titlePanel("BC Electoral Districts--Selected data"),
mainPanel(leafletOutput("BCFEDS"))
)
# Define server logic required to draw a histogram
server <- function(input, output) {
output$BCFEDS <- renderLeaflet(
{
#This code works
BCFEDS <- leaflet()
BCFEDS <- addTiles(BCFEDS)
BCFEDS <- setView(BCFEDS, lng = -122.8, lat = 49.3, zoom = 8)
BCFEDS <- addPolygons(data = new_bc_fed_C, map = BCFEDS)
BCFEDS <- addMarkers(map = BCFEDS, lng = new_bc_fed_C$X , lat = new_bc_fed_C$Y, popup = as.character(new_bc_fed_C$LANDAREA))
#This code does not work
BCFEDS <- leaflet()
BCFEDS <- addTiles(BCFEDS)
BCFEDS <- setView(BCFEDS, lng = -122.8, lat = 49.3, zoom = 8)
BCFEDS <- addPolygons(data = bc_fed_nova, map = BCFEDS)
BCFEDS <- addMarkers(map = BCFEDS, lng = bc_fed_nova$X , lat = bc_fed_nova$Y, popup = as.character(bc_fed_nova$Shape_Area))
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
Obviously, I comment out one of the two blocks of code as needed when I run it.
This is what it looks like when it's working:
This is what it looks like when it's not working:
Is the reason that one works and not the other that I added columns to the data frame using the left_join
function from dplyr
?
Okay, I've figured it out. It was actually a simple mistake all along: I forgot to transform the coordinate system of the map I wanted to use with the sf::st_transform()
function. As a result, the coordinate system was all over the place and that's why I couldn't see the markers.
Sorry about the confusion and thank you to @Jan.