Adding features

Programmatically, adding, deleting, or updating features using arcgis is a straightforward process. In this workflow, we illustrate how to add, update, or delete features from an existing hosted feature layer or table.

We will go over the functions:

Pre-requisites

We will use the the North Carolina SIDS dataset we created in the Publishing layers tutorial. To follow along, be sure that you have followed that tutorial and have a FeatureLayer that you can modify. If you have not yet configured your environment to authorize with an online portal, start at Connecting to your portal.

Adding features

For this example, we will add a single feature to the North Carolina SIDS dataset that is a summary over the entire state. Before we can begin, we must load the package and authorize ourselves as a user.

library(arcgis)

token <- auth_code()
set_auth_token(token)

Next, we will create the feature that we want to add using the sf package. We’ll read in the nc.shp file from the sf package.

library(sf)
nc_sf <- read_sf(system.file("shape/nc.shp", package = "sf"))
nc_sf
#> Simple feature collection with 100 features and 14 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS:  NAD27
#> # A tibble: 100 × 15
#>     AREA PERIMETER CNTY_ CNTY_ID NAME        FIPS  FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79
#>    <dbl>     <dbl> <dbl>   <dbl> <chr>       <chr>  <dbl>    <int> <dbl> <dbl>   <dbl> <dbl> <dbl>   <dbl>
#>  1 0.114      1.44  1825    1825 Ashe        37009  37009        5  1091     1      10  1364     0      19
#>  2 0.061      1.23  1827    1827 Alleghany   37005  37005        3   487     0      10   542     3      12
#>  3 0.143      1.63  1828    1828 Surry       37171  37171       86  3188     5     208  3616     6     260
#>  4 0.07       2.97  1831    1831 Currituck   37053  37053       27   508     1     123   830     2     145
#>  5 0.153      2.21  1832    1832 Northampton 37131  37131       66  1421     9    1066  1606     3    1197
#>  6 0.097      1.67  1833    1833 Hertford    37091  37091       46  1452     7     954  1838     5    1237
#>  7 0.062      1.55  1834    1834 Camden      37029  37029       15   286     0     115   350     2     139
#>  8 0.091      1.28  1835    1835 Gates       37073  37073       37   420     0     254   594     2     371
#>  9 0.118      1.42  1836    1836 Warren      37185  37185       93   968     4     748  1190     2     844
#> 10 0.124      1.43  1837    1837 Stokes      37169  37169       85  1612     1     160  2038     5     176
#> # ℹ 90 more rows
#> # ℹ 1 more variable: geometry <MULTIPOLYGON [°]>

Let’s calculate the average birth rate, SIDS rate, and the non-white birth rate and SIDS rate for the entire state. We will add this as a single feature to our existing feature layer. To do so, we will use the R package dplyr for manipulating our data.

library(dplyr)

nc_summary <- nc_sf |>  
  summarise(
    across( # <1>
      .cols = c(ends_with("74"), ends_with("79")), # <2>
      .fns = mean # <3>
    ),
    NAME = "Total" # <4>
  ) 

nc_summary
#> Simple feature collection with 1 feature and 7 fields
#> Geometry type: MULTIPOLYGON
#> Dimension:     XY
#> Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> Geodetic CRS:  NAD27
#> # A tibble: 1 × 8
#>   BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79 NAME                                                                 geometry
#>   <dbl> <dbl>   <dbl> <dbl> <dbl>   <dbl> <chr>                                                      <MULTIPOLYGON [°]>
#> 1 3300.  6.67   1051. 4224.  8.36   1353. Total (((-75.97629 36.51793, -75.97728 36.47802, -75.9248 36.47398, -75.9119…
  1. The across() function applies a function to multiple columns at once.
  2. We specify the columns we will be applying a function to in .cols. We use the tidyselect helpers to catch any columns that end with 74 or 79.
  3. The .fns argument specifies which functions will be applied to the columns. In this case, we apply on the mean() function to calculate the average.
  4. The NAME field is set manually to the value of "Total" to indicate that it is not a county.

In order to add this new aggregate feature to the FeatureLayer we must create a reference to the layer using arc_open().

nc_url <- "https://services1.arcgis.com/hLJbHVT9ZrDIzK0I/arcgis/rest/services/North%20Carolina%20SIDS/FeatureServer/0" 

nc <- arc_open(nc_url)
<FeatureLayer>
Name: North Carolina SIDS
Geometry Type: esriGeometryPolygon
CRS: 4267
Capabilities: Create,Delete,Query,Update,Editing

The url you use here will be different than the one you see. Be sure to grab the correct url from the content listing for your item.

Now that we have a FeatureLayer object we can add features to it using add_features(). There are a few key arguments to the function:

  • x is the FeatureLayer object that we want to add features to
  • .data is an sf object that we want to add to the FeatureLayer
  • match_on determines how to match sf columns to FeatureLayer fields

By default, add_features() will compare the column names of the sf object to that of the FeatureLayer. We can find the field names and aliases for a FeatureLayer by using the list_fields() function. Pass the results to tibble::as_tibble() to make them more readable.

Since we know that the column names match those of the FeatureLayer, we can pass nc_summary directly to add_feature().

add_res <- add_features(nc, nc_summary)
add_res
  objectId uniqueId globalId success
1      101      101       NA    TRUE

If you are adding many features at one time, consider changing the value of chunk_size. By default, add_features() will add up to 2000 features at a time and send the requests in parallel. Depending on the geometry type and precision, it may be worthwhile to make that number smaller. If the data are truly massive, consider breaking up the task into smaller manageable chunks.

Once we’ve added the results to the FeatureLayer, we may want to refresh the object to catch any important changes to the metadata.

nc <- refresh_layer(nc)
<FeatureLayer>
Name: North Carolina SIDS
Geometry Type: esriGeometryPolygon
CRS: 4267
Capabilities: Create,Delete,Query,Update,Editing

We can see that the FeatureLayer now has 101 features as opposed to the original 100. To sanity check, we can query nc to see how the value comes back.

nc_avgs <- nc |> 
  filter(NAME == "Total") |> 
  collect()

nc_avgs
Simple feature collection with 1 feature and 15 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
Geodetic CRS:  NAD27
  object_id AREA PERIMETER CNTY_ CNTY_ID  NAME FIPS FIPSNO CRESS_ID   BIR74 SID74 NWBIR74   BIR79 SID79 NWBIR79                       geometry
1       101   NA        NA    NA      NA Total   NA     NA       NA 3299.62  6.67 1050.81 4223.92  8.36 1352.81 MULTIPOLYGON (((-75.9248 36...

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.