-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
91e3cb3
commit 254fc4e
Showing
4 changed files
with
212 additions
and
26 deletions.
There are no files selected for viewing
15 changes: 15 additions & 0 deletions
15
_freeze/location-services/workflows/add-delete-update/execute-results/html.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"hash": "7265e9c90ee8725549c28e8ca937350c", | ||
"result": { | ||
"engine": "knitr", | ||
"markdown": "---\ntitle: \"Editing Features\"\nsubtitle: \"Learn to add, update, or delete features\"\nfreeze: true\n---\n\n\n\n\nProgrammatically, adding, deleting, or updating features using `{arcgis}` is a deceptively simple process. In this workflow, we illustrate how to add, update, or delete features from an existing hosted Feature Layer or Table. \n\nWe will go over the functions:\n\n - `add_features()`\n - `update_features()`\n - `delete_features()`\n \n## Pre-requisites\n\nWe will use the the *North Carolina SIDS* dataset we created in the [**Publishing from R**](../publishing.qmd) 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**](../connecting-to-a-portal.qmd).\n\n## Adding features\n\nFor 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. \n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(arcgis)\n\ntoken <- auth_code()\nset_auth_token(token)\n```\n:::\n\n```\n#> Token set to environment variable `ARCGIS_TOKEN`\n```\n\nNext, 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.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(sf)\nnc_sf <- read_sf(system.file(\"shape/nc.shp\", package = \"sf\"))\nnc_sf\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\nSimple feature collection with 100 features and 14 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965\nGeodetic CRS: NAD27\n# A tibble: 100 × 15\n AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74\n <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl> <int> <dbl> <dbl> <dbl>\n 1 0.114 1.44 1825 1825 Ashe 37009 37009 5 1091 1 10\n 2 0.061 1.23 1827 1827 Alle… 37005 37005 3 487 0 10\n 3 0.143 1.63 1828 1828 Surry 37171 37171 86 3188 5 208\n 4 0.07 2.97 1831 1831 Curr… 37053 37053 27 508 1 123\n 5 0.153 2.21 1832 1832 Nort… 37131 37131 66 1421 9 1066\n 6 0.097 1.67 1833 1833 Hert… 37091 37091 46 1452 7 954\n 7 0.062 1.55 1834 1834 Camd… 37029 37029 15 286 0 115\n 8 0.091 1.28 1835 1835 Gates 37073 37073 37 420 0 254\n 9 0.118 1.42 1836 1836 Warr… 37185 37185 93 968 4 748\n10 0.124 1.43 1837 1837 Stok… 37169 37169 85 1612 1 160\n# ℹ 90 more rows\n# ℹ 4 more variables: BIR79 <dbl>, SID79 <dbl>, NWBIR79 <dbl>,\n# geometry <MULTIPOLYGON [°]>\n```\n\n\n:::\n:::\n\n\nLet'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`](https://dplyr.tidyverse.org/) for manipulating our data.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nlibrary(dplyr)\n\nnc_summary <- nc_sf |> \n summarise(\n across( # <1>\n .cols = c(ends_with(\"74\"), ends_with(\"79\")), # <2>\n .fns = mean # <3>\n ),\n NAME = \"Total\" # <4>\n ) \n\nnc_summary\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\nSimple feature collection with 1 feature and 7 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965\nGeodetic CRS: NAD27\n# A tibble: 1 × 8\n BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79 NAME geometry\n <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <MULTIPOLYGON [°]>\n1 3300. 6.67 1051. 4224. 8.36 1353. Total (((-75.97629 36.51793, -75.9772…\n```\n\n\n:::\n:::\n\n1. The [`across()`](https://dplyr.tidyverse.org/reference/across.html) function applies a function to multiple columns at once.\n2. We specify the columns we will be apply a function to in `.cols`. We use the `tidyselect` helpers to catch any columns that end with `74` or `79`.\n3. 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. \n4. The `NAME` field is set manually to the value of `\"Total\"` to indicate that it is not a county. \n\nIn order to add this new aggregate feature to the `FeatureLayer` we must create a reference to the layer using `arc_open()`. \n\n\n::: {.cell}\n\n```{.r .cell-code}\nnc_url <- \"https://services1.arcgis.com/hLJbHVT9ZrDIzK0I/arcgis/rest/services/North%20Carolina%20SIDS/FeatureServer/0\" \n\nnc <- arc_open(nc_url)\n```\n:::\n\n```\n<FeatureLayer <100 features, 15 fields>>\nName: North Carolina SIDS\nGeometry Type: esriGeometryPolygon\nCRS: 4267\nCapabilities: Create,Delete,Query,Update,Editing\n```\n:::{.aside}\nThe url you use here will be different than the one you see. Be sure to grab the correct url from the content listing. \n:::\n\nNow that we have a `FeatureLayer` object we can add features to it using `add_features()`. There are a few key arguments to the function:\n\n- `x` is the `FeatureLayer` object that we want to add features to \n- `.data` is an `sf` object that we want to add to the `FeatureLayer`\n- `match_on` determines how to match sf columns to `FeatureLayer` fields\n\nBy 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.\n\nSince we know that the column names match those of the `FeatureLayer` we can pass `nc_summary` directly to `add_feature()`.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nadd_res <- add_features(nc, nc_summary)\nadd_res\n```\n:::\n\n```\n objectId uniqueId globalId success\n1 101 101 NA TRUE\n```\n\n:::{.callout-tip}\nIf you are adding a lot of 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. \n:::\n\nOnce we've added the results to the `FeatureLayer`, we may want to refresh the object to catch any important changes to the metadata. \n\n\n::: {.cell}\n\n```{.r .cell-code}\nnc <- refresh_layer(nc)\n```\n:::\n\n```\n<FeatureLayer <101 features, 15 fields>>\nName: North Carolina SIDS\nGeometry Type: esriGeometryPolygon\nCRS: 4267\nCapabilities: Create,Delete,Query,Update,Editing\n```\n\nWe 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.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nnc_avgs <- nc |> \n filter(NAME == \"Total\") |> \n collect()\n\nnc_avgs\n```\n:::\n\n```\nSimple feature collection with 1 feature and 15 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965\nGeodetic CRS: NAD27\n object_id AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79 geometry\n1 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...\n```\n\n## Updating Features\n\n\nIn the previous section we added a new feature that is the average of our numeric columns and stored the results in the variable `nc_totals`. When looking at it, we can see that the `AREA` AND `PERIMTER` values are missing. These might be helpful at a later point. \n\nIn this section we will use the function `update_features()` to modify these values. First, let's create a new object called `to_update` that has the `AREA` and `PERIMETER` computed. \n\n\n::: {.cell}\n\n```{.r .cell-code}\nnc_avgs |> \n mutate(\n AREA = st_area(geometry) / 1e10,\n PERIMETER = s2::s2_perimeter(geometry) / 1e5\n )\n```\n:::\n\n```\nSimple feature collection with 1 feature and 15 fields\nGeometry type: MULTIPOLYGON\nDimension: XY\nBounding box: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965\nGeodetic CRS: NAD27\n object_id AREA PERIMETER CNTY_ CNTY_ID NAME FIPS FIPSNO CRESS_ID BIR74 SID74 NWBIR74 BIR79 SID79 NWBIR79 geometry\n1 101 12.70259 [m^2] 33.58819 NA NA Total NA NA NA 3299.62 6.67 1050.81 4223.92 8.36 1352.81 MULTIPOLYGON (((-75.9248 36...\n```\n\n\nLike `add_features()`, we need to match the field names \n\n\n\n\n\n\n", | ||
"supporting": [], | ||
"filters": [ | ||
"rmarkdown/pagebreak.lua" | ||
], | ||
"includes": {}, | ||
"engineDependencies": {}, | ||
"preserve": {}, | ||
"postProcess": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
--- | ||
title: "Editing Features" | ||
subtitle: "Learn to add, update, or delete features" | ||
freeze: true | ||
--- | ||
|
||
```{r, include = FALSE} | ||
knitr::opts_chunk$set(eval = FALSE) | ||
``` | ||
|
||
Programmatically, adding, deleting, or updating features using `{arcgis}` is a deceptively simple 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: | ||
|
||
- `add_features()` | ||
- `update_features()` | ||
- `delete_features()` | ||
|
||
## Pre-requisites | ||
|
||
We will use the the *North Carolina SIDS* dataset we created in the [**Publishing from R**](../publishing.qmd) 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**](../connecting-to-a-portal.qmd). | ||
|
||
## 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. | ||
|
||
```{r} | ||
library(arcgis) | ||
token <- auth_code() | ||
set_auth_token(token) | ||
``` | ||
``` | ||
#> Token set to environment variable `ARCGIS_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. | ||
|
||
```{r eval = TRUE, message = FALSE} | ||
library(sf) | ||
nc_sf <- read_sf(system.file("shape/nc.shp", package = "sf")) | ||
nc_sf | ||
``` | ||
|
||
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`](https://dplyr.tidyverse.org/) for manipulating our data. | ||
|
||
```{r, message = FALSE, eval = TRUE} | ||
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 | ||
``` | ||
1. The [`across()`](https://dplyr.tidyverse.org/reference/across.html) function applies a function to multiple columns at once. | ||
2. We specify the columns we will be apply 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()`. | ||
|
||
```{r} | ||
nc_url <- "https://services1.arcgis.com/hLJbHVT9ZrDIzK0I/arcgis/rest/services/North%20Carolina%20SIDS/FeatureServer/0" | ||
nc <- arc_open(nc_url) | ||
``` | ||
``` | ||
<FeatureLayer <100 features, 15 fields>> | ||
Name: North Carolina SIDS | ||
Geometry Type: esriGeometryPolygon | ||
CRS: 4267 | ||
Capabilities: Create,Delete,Query,Update,Editing | ||
``` | ||
:::{.aside} | ||
The url you use here will be different than the one you see. Be sure to grab the correct url from the content listing. | ||
::: | ||
|
||
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()`. | ||
|
||
```{r} | ||
add_res <- add_features(nc, nc_summary) | ||
add_res | ||
``` | ||
``` | ||
objectId uniqueId globalId success | ||
1 101 101 NA TRUE | ||
``` | ||
|
||
:::{.callout-tip} | ||
If you are adding a lot of 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. | ||
|
||
```{r} | ||
nc <- refresh_layer(nc) | ||
``` | ||
``` | ||
<FeatureLayer <101 features, 15 fields>> | ||
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. | ||
|
||
```{r} | ||
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... | ||
``` | ||
|
||
## Updating Features | ||
|
||
|
||
In the previous section we added a new feature that is the average of our numeric columns and stored the results in the variable `nc_totals`. When looking at it, we can see that the `AREA` AND `PERIMTER` values are missing. These might be helpful at a later point. | ||
|
||
In this section we will use the function `update_features()` to modify these values. First, let's create a new object called `to_update` that has the `AREA` and `PERIMETER` computed. | ||
|
||
```{r} | ||
nc_avgs |> | ||
mutate( | ||
AREA = st_area(geometry) / 1e10, | ||
PERIMETER = s2::s2_perimeter(geometry) / 1e5 | ||
) | ||
``` | ||
``` | ||
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 12.70259 [m^2] 33.58819 NA NA Total NA NA NA 3299.62 6.67 1050.81 4223.92 8.36 1352.81 MULTIPOLYGON (((-75.9248 36... | ||
``` | ||
|
||
|
||
Like `add_features()`, we need to match the field names | ||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters