Search code examples
rloopsopenstreetmap

How to iterate my code to calculate total street length (OSM) per city?


I have the following R code, and I want to iterate it over a data frame called ucb.world.cities. This script calculates for each city (rows) of the data frame the total length of pedestrian streets (based on osm data) and in turn, exports a .csv file with the result per each urban area as well as a .shapefile with the lines of pedestrian streets. However, the data frame includes about 996 city cases, and I do not want to repeat the process manually for each city separately. So, I welcome any ideas on how to iterate the code.

    library(osmdata)
    library(sf)
    library(dplyr)

> head(ucb.world.cities)
# A tibble: 6 x 10
  ID_HDC_G0 BBX_LATMN BBX_LONMN BBX_LATMX BBX_LONMX  AREA XC_NM_LST UC_NM_MN                                 GRGN_L1 GRGN_L2        
      <dbl>     <dbl>     <dbl>     <dbl>     <dbl> <dbl> <chr>     <chr>                                    <chr>   <chr>          
1      3244      60.1      24.7      60.3      25.2   344 Finland   Helsinki [FIN]                           Europe  Northern Europe
2      2493      59.8      10.5      60.0      11.0   242 Norway    Oslo [NOR]                               Europe  Northern Europe
3      3396      59.8      30.1      60.1      30.6   527 Russia    Sankt Peterburg (Saint Petersburg) [RUS] Europe  Eastern Europe 
4      2973      59.2      17.8      59.5      18.3   361 Sweden    Stockholm [SWE]                          Europe  Northern Europe
5      3739      57.5      39.7      57.7      40.0   166 Russia    Yaroslavl [RUS]                          Europe  Eastern Europe 
6      5735      57.1      65.4      57.2      65.7   155 Russia    Tyumen [RUS]                             Europe  Eastern Europe 
> 

    q001<- opq(bbox=c(ucb.world.cities$BBX_LONMN[1], 
                               ucb.world.cities$BBX_LATMN[1], 
                               ucb.world.cities$BBX_LONMX[1], 
                               ucb.world.cities$BBX_LATMX[1])) %>%
        add_osm_feature(key="highway", value="pedestrian") 

        pedestrianA<- osmdata_sf(q001)
        pedestrianB<- pedestrianA[["osm_lines"]]
        pedestrianC<- subset(pedestrianB, name != "NA")

        city001<- st_geometry(pedestrianC)
        city001<- st_intersection(city001, ucb.world.cities_spatial)
        setwd("C:/Users/Alex/Desktop/R_Analysis_July2019/Shapefiles_PedestrianStreets_with_Address")
        st_write(city001, dsn = paste0(ucb.world.cities$UC_NM_MN[1],".shp"), driver = "ESRI Shapefile")
        city001_length<- st_length(city001)

        result001<- as.data.frame(sum(city001_length))
        colnames(result001)[1]<- "Pedestrian.Str.Names.meters"
        result001[, "UC_NM_MN"]<- paste0(ucb.world.cities$UC_NM_MN[1])      
        result001[, "ID_HDC_G0"]<- paste0(ucb.world.cities$ID_HDC_G0[1])
        setwd("C:/Users/Alex/Desktop/R_Analysis_July2019/Tables_PedestrianStreets_with_Address")
        write.csv(result001, file=paste0(ucb.world.cities$UC_NM_MN[1],".csv"))

Solution

  • for(i in 1:nrow(ucb.world.cities)){ # iterates from 1 : number of rows in your data frame
    
    q001<- opq(bbox=c(ucb.world.cities$BBX_LONMN[i], #[i] will get index 1: to number of rows in your data frame 
                      ucb.world.cities$BBX_LATMN[i], 
                      ucb.world.cities$BBX_LONMX[i], 
                      ucb.world.cities$BBX_LATMX[i])) %>%
      add_osm_feature(key="highway", value="pedestrian") 
    
    pedestrianA<- osmdata_sf(q001)
    pedestrianB<- pedestrianA[["osm_lines"]]
    pedestrianC<- subset(pedestrianB, name != "NA")
    
    city001<- st_geometry(pedestrianC)
    city001<- st_intersection(city001, ucb.world.cities_spatial)
    setwd("C:/Users/Alex/Desktop/R_Analysis_July2019/Shapefiles_PedestrianStreets_with_Address")
    st_write(city001, dsn = paste0(ucb.world.cities$UC_NM_MN[i],".shp"), driver = "ESRI Shapefile")
    city001_length<- st_length(city001)
    
    result001<- as.data.frame(sum(city001_length))
    colnames(result001)[1]<- "Pedestrian.Str.Names.meters" #presume you want to rename just the first column here and not iterate over..
    result001[, "UC_NM_MN"]<- paste0(ucb.world.cities$UC_NM_MN[i])      
    result001[, "ID_HDC_G0"]<- paste0(ucb.world.cities$ID_HDC_G0[i])
    setwd("C:/Users/Alex/Desktop/R_Analysis_July2019/Tables_PedestrianStreets_with_Address")
    write.csv(result001, file=paste0(ucb.world.cities$UC_NM_MN[i],".csv"))
    
    }