Search code examples
rspatialkml

How to separate a dataframe by group and then write separate KML files for each group in R?


I have a data frame that has latitudes and longitudes along with attributes. I want to split this data frame up by grouping one of the columns and write these groups into separate KML files in R. For example I want separate KML files based on color (one for Blue, one for Green, and one for Red). For reference, my actual data set I have 50+ colors.

    Name Latitude   Longitude Color
   Dawn 48.93553 -111.677777  Blue
   Lore 45.13333 -114.888888 Green
   Nice 40.73499 -114.999900  Blue
    Cat 41.89999 -114.999200   Red
   Lake 48.99678 -116.787876   Red
 Forest 42.88889 -112.999900   Red

Solution

  • You could first convert your data.frame to sf object, it can be split() to named list as a regular data.frame, and then save each part as KML through sf::st_write(). purrr::iwalk() cycles though the list and can also access list names, so the split factor ends up in file names too.

    library(sf)
    #> Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
    
    df_ <- read.table(header = T, text ="
       Name Latitude   Longitude Color
       Dawn 48.93553 -111.677777  Blue
       Lore 45.13333 -114.888888 Green
       Nice 40.73499 -114.999900  Blue
        Cat 41.89999 -114.999200   Red
       Lake 48.99678 -116.787876   Red
     Forest 42.88889 -112.999900   Red")
    
    st_as_sf(df_, coords = c("Longitude", "Latitude"), crs = "WGS84") |>
      split(~ Color) |>
      purrr::iwalk(\(features, color) st_write(features, paste0(color,".kml")))
    #> Writing layer `Blue' to data source `Blue.kml' using driver `KML'
    #> Writing 2 features with 2 fields and geometry type Point.
    #> Writing layer `Green' to data source `Green.kml' using driver `KML'
    #> Writing 1 features with 2 fields and geometry type Point.
    #> Writing layer `Red' to data source `Red.kml' using driver `KML'
    #> Writing 3 features with 2 fields and geometry type Point.
    

    Resulting files:

    fs::dir_info(glob = "*.kml")[1:5]
    #> # A tibble: 3 × 5
    #>   path       type         size permissions modification_time  
    #>   <fs::path> <fct> <fs::bytes> <fs::perms> <dttm>             
    #> 1 Blue.kml   file          559 rw-         2023-03-23 23:09:14
    #> 2 Green.kml  file          415 rw-         2023-03-23 23:09:14
    #> 3 Red.kml    file          702 rw-         2023-03-23 23:09:14
    

    Created on 2023-03-23 with reprex v2.0.2