Data Models, Coordinates, and Geometries

Objectives

We’re going to introduce the sf, terra, and tidyterra packages today as a way of reading and inspecting spatial data. By the end of this lesson, you should be able to:

  1. Read in spatial data from both the vector and raster data model.

  2. Recognize the required components of a spatial data object

  3. Use plot as a way to perform a quick check on your data.

Getting Started

First, join the repository. Then, we’ll have to get our credentials and login to a new RStudio session. Finally, create a new, version control, git-based project (using the link to the repo you just created).

Once you’ve done that, you’ll need to load your packages. We’re going to add 3 new packages to the tidyverse; the sf, terra, and tidyterra packages. We’ll also add the googledrive so that we can use a custom function for downloading data from a shared Google Drive folder. Note that when you load these, the conflicts that the tidyverse reports will be different. In order to overcome these conflicts, you’ll need to use explicit calls like package::function so R knows which ones to use.

Code
library(googledrive)
library(sf)
Linking to GEOS 3.13.0, GDAL 3.8.5, PROJ 9.5.1; sf_use_s2() is TRUE
Code
library(terra)
terra 1.8.70
Code
library(tidyterra)

Attaching package: 'tidyterra'
The following object is masked from 'package:stats':

    filter
Code
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.1     ✔ stringr   1.5.2
✔ ggplot2   4.0.0     ✔ tibble    3.3.0
✔ lubridate 1.9.4     ✔ tidyr     1.3.1
✔ purrr     1.1.0     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ tidyr::extract() masks terra::extract()
✖ dplyr::filter()  masks tidyterra::filter(), stats::filter()
✖ dplyr::lag()     masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Loading a Custom Function

You’ll notice that your scripts/utilities folder has a file called download_utils.R. This file has some custom functions for downloading data directly from websites and from a Google Drive Folder. In order to give yourself access to these functions you’ll need to source them into your environment. You can do this by typing:

Code
source("scripts/utilities/download_utils.R")

The first time you run the gdrive_folder_download function, you’ll be taken to a webpage where you need to give googledrive access to your Google Drive folders. Make sure you’ve checked all the boxes and click Allow. You should get a message saying that authorization is complete and that you can close the tab.

Let’s run it now and download the data to our original folder. You’ll see that it requires two arguments, filelst and dstfldr. The first is a list of files in the folder, the second is the name of the destination folder. In order to generate the filelst we need to do some googledrive gymnastics to generate a data frame of the unique google drive id’s for each file. We then use pmap to download each file. You’ll notice that the destination path is printed to the screen.

Code
file_list <- drive_ls(drive_get(as_id("https://drive.google.com/drive/u/1/folders/1PwfUX2hnJlbnqBe3qvl33tFBImtNFTuR")))[-1,]
! Using an auto-discovered, cached token.
  To suppress this message, modify your code or options to clearly consent to
  the use of a cached token.
  See gargle's "Non-interactive auth" vignette for more details:
  <https://gargle.r-lib.org/articles/non-interactive-auth.html>
ℹ The googledrive package is using a cached token for
  'mattwilliamson@boisestate.edu'.
Auto-refreshing stale OAuth token.
Code
file_list %>% 
  dplyr::select(id, name) %>%
  purrr::pmap(function(id, name) {
    gdrive_folder_download(list(id = id, name = name),
                           dstfldr = "inclass07")
  })
File downloaded:
• 'blockgroupPop.shx' <id: 10RKLXNzoNfYQralSDDbsAkxgwSGgc46w>
Saved locally as:
• 'data/original/inclass07/blockgroupPop.shx'
File downloaded:
• 'blockgroupPop.shp' <id: 19HSGozYvuqmXQ-CtPVkwFcFmDK-V6aIr>
Saved locally as:
• 'data/original/inclass07/blockgroupPop.shp'
File downloaded:
• 'blockgroupPop.dbf' <id: 14alTpZHGZ067Ez1270Q7ffiVKO4zbY3p>
Saved locally as:
• 'data/original/inclass07/blockgroupPop.dbf'
File downloaded:
• 'blockgroupPop.prj' <id: 1QbV7Dn53zM_KvuUKc7rBug9R5lRg3rFy>
Saved locally as:
• 'data/original/inclass07/blockgroupPop.prj'
File downloaded:
• 'paReadings.csv' <id: 184wxWw1DQrllUAFUnXtR0TSMYVqWUJ_G>
Saved locally as:
• 'data/original/inclass07/paReadings.csv'
File downloaded:
• 'pa_pt_locations.shx' <id: 14rFc7Hxgxl6QfuhfYtRDvNE6TOYUnho4>
Saved locally as:
• 'data/original/inclass07/pa.shx'
File downloaded:
• 'pa_pt_locations.shp' <id: 15zHbHjWhcuxT0sgOuElDAh1QgOYEbjZN>
Saved locally as:
• 'data/original/inclass07/pa.shp'
File downloaded:
• 'pa_pt_locations.dbf' <id: 13yZY6gkyd7GT7MVL5vOwI8xMcPCCZrTs>
Saved locally as:
• 'data/original/inclass07/pa.dbf'
File downloaded:
• 'pa_pt_locations.prj' <id: 1yC1NjbbrbWAMiiJjcTobzfg252ah-pek>
Saved locally as:
• 'data/original/inclass07/pa.prj'
File downloaded:
• 'pa_censors_loc.csv' <id: 13ZPu8E96ERWdUNlwQ5MB_vXrPCqvzxj_>
Saved locally as:
• 'data/original/inclass07/pa.csv'
File downloaded:
• 'wildfire_hazard_agg.tif' <id: 135PvMlKu17i7tZcrF7XiWxzrzaX-aCLn>
Saved locally as:
• 'data/original/inclass07/wildfire.tif'
File downloaded:
• 'cejst_nw.shx' <id: 1IXDayQ35MwCfq1UtuDHCtf5iNYq5VUqu>
Saved locally as:
• 'data/original/inclass07/cejst.shx'
File downloaded:
• 'cejst_nw.dbf' <id: 1PgCOsZsVEOhxQs2Dpz21MNz0kMb32amB>
Saved locally as:
• 'data/original/inclass07/cejst.dbf'
File downloaded:
• 'cejst_nw.shp' <id: 1ZeL_683mTTWdCDjQ4dY6oJsxyVZtQT6O>
Saved locally as:
• 'data/original/inclass07/cejst.shp'
File downloaded:
• 'cejst_nw.prj' <id: 1r7OHK1DHhoEMBToiM2FmuK5xmEzWSdrc>
Saved locally as:
• 'data/original/inclass07/cejst.prj'
[[1]]
[1] "data/original/inclass07/blockgroupPop.shx"

[[2]]
[1] "data/original/inclass07/blockgroupPop.shp"

[[3]]
[1] "data/original/inclass07/blockgroupPop.dbf"

[[4]]
[1] "data/original/inclass07/blockgroupPop.prj"

[[5]]
[1] "data/original/inclass07/paReadings.csv"

[[6]]
[1] "data/original/inclass07/pa.shx"

[[7]]
[1] "data/original/inclass07/pa.shp"

[[8]]
[1] "data/original/inclass07/pa.dbf"

[[9]]
[1] "data/original/inclass07/pa.prj"

[[10]]
[1] "data/original/inclass07/pa.csv"

[[11]]
[1] "data/original/inclass07/wildfire.tif"

[[12]]
[1] "data/original/inclass07/cejst.shx"

[[13]]
[1] "data/original/inclass07/cejst.dbf"

[[14]]
[1] "data/original/inclass07/cejst.shp"

[[15]]
[1] "data/original/inclass07/cejst.prj"

Reading Data: Vectors

The vector data (called cejst) comes from the Climate and Environmental Justice Screening Tool which is no longer available online. You’ll notice that there are multiple files with the same name, but different extensions. We’ll talk more about these different files in the next few weeks, but for now, just not that these files exist.

Because sf adheres to the tidyverse grammars, we can use a similar intuition to read in the data. You’ll note that even though we have all these extra files, we only need the .shp file. This is the shapefile which is the “overarching” file for all of the data.

Code
cejst_shp <- read_sf("data/original/inclass07/cejst.shp")

Now that you’ve got the data in, let’s take a look at it using str and glimpse.

Code
str(cejst_shp)
sf [2,590 × 124] (S3: sf/tbl_df/tbl/data.frame)
 $ GEOID10   : chr [1:2590] "16019970700" "16025970100" "16027021700" "16027020700" ...
 $ SF        : chr [1:2590] "Idaho" "Idaho" "Idaho" "Idaho" ...
 $ CF        : chr [1:2590] "Bonneville County" "Camas County" "Canyon County" "Canyon County" ...
 $ DF_PFS    : num [1:2590] 0.44 0.67 0.74 0.48 0.75 0.8 0.76 0.72 0.76 0.52 ...
 $ AF_PFS    : num [1:2590] 0.73 0.65 0.86 0.63 0.79 0.88 0.86 0.79 0.8 0.65 ...
 $ HDF_PFS   : num [1:2590] 0.57 0.79 0.69 0.47 0.72 0.55 0.53 0.71 0.74 0.45 ...
 $ DSF_PFS   : num [1:2590] 0.53 0 0.58 0.46 0.12 0.79 0.68 0.27 0.06 0.11 ...
 $ EBF_PFS   : num [1:2590] 0.63 0.95 0.54 0.3 0.63 0.81 0.81 0.44 0.73 0.52 ...
 $ EALR_PFS  : num [1:2590] 0.55 0.83 0.63 0.63 0.65 NA 0.41 0.64 0.65 0.64 ...
 $ EBLR_PFS  : num [1:2590] 0.19 0.93 0.05 0.55 0.09 0.09 0.08 0.09 0.47 0.17 ...
 $ EPLR_PFS  : num [1:2590] 0.8 0.99 0.09 0.1 0.11 0.31 0.08 0.09 0.1 0.09 ...
 $ HBF_PFS   : num [1:2590] 0.69 0.6 0.53 0.07 0.46 0.86 0.93 0.22 0.53 0.28 ...
 $ LLEF_PFS  : num [1:2590] 0.73 0.48 0.67 0.29 0.51 0.87 0.62 0.38 0.32 0.26 ...
 $ LIF_PFS   : num [1:2590] 0.54 0.54 0.53 0.12 0.48 0.61 0.88 0.46 0.41 0.32 ...
 $ LMI_PFS   : num [1:2590] 0.81 0.75 0.61 0.25 0.55 0.92 0.95 0.44 0.42 0.35 ...
 $ PM25F_PFS : num [1:2590] 0.11 0 0.68 0.63 0.42 0.66 0.69 0.57 0.26 0.4 ...
 $ HSEF      : num [1:2590] 0.14 0.06 0.2 0.08 0.21 0.24 0.31 0.18 0.18 0.09 ...
 $ P100_PFS  : num [1:2590] 0.83 0.63 0.47 0.24 0.6 0.72 0.93 0.27 0.39 0.33 ...
 $ P200_I_PFS: num [1:2590] 0.86 0.71 0.81 0.39 0.75 0.98 0.91 0.49 0.67 0.54 ...
 $ AJDLI_ET  : int [1:2590] 1 1 1 0 1 1 1 0 1 1 ...
 $ LPF_PFS   : num [1:2590] 0.75 0.52 0.26 0.3 0.65 0.62 0.63 0.4 0.51 0.36 ...
 $ KP_PFS    : num [1:2590] 0.86 0.21 0.84 0.21 0.61 0.57 0.21 0.43 0.9 0.21 ...
 $ NPL_PFS   : num [1:2590] 0.09 0.05 0.06 0.08 0.03 0.08 0.05 0.05 0.08 0.1 ...
 $ RMP_PFS   : num [1:2590] 0.49 0.01 0.56 0.84 0.26 0.96 0.58 0.36 0.1 0.2 ...
 $ TSDF_PFS  : num [1:2590] 0.22 0.01 0.14 0.42 0.07 0.55 0.13 0.11 0.1 0.19 ...
 $ TPF       : num [1:2590] 5589 1048 11701 3901 5059 ...
 $ TF_PFS    : num [1:2590] 0.55 0.06 0.54 0.53 0.28 0.71 0.83 0.24 0.05 0.09 ...
 $ UF_PFS    : num [1:2590] 0.61 0.16 0.64 0.33 0.66 0.86 0.8 0.45 0.47 0.61 ...
 $ WF_PFS    : num [1:2590] 0.03 0.11 0.98 0.24 0.79 0.98 0.98 0.85 0.42 0.04 ...
 $ UST_PFS   : num [1:2590] 0.59 0.02 0.44 0.31 0.17 0.73 0.83 0.13 0.06 0.18 ...
 $ N_WTR     : int [1:2590] 0 0 1 0 0 1 1 0 0 0 ...
 $ N_WKFC    : int [1:2590] 0 0 0 0 0 1 1 0 0 0 ...
 $ N_CLT     : int [1:2590] 0 1 0 0 0 1 1 0 0 0 ...
 $ N_ENY     : int [1:2590] 0 1 0 0 0 0 0 0 0 0 ...
 $ N_TRN     : int [1:2590] 0 0 0 0 0 0 0 0 1 0 ...
 $ N_HSG     : int [1:2590] 0 0 0 0 0 0 1 0 1 0 ...
 $ N_PLN     : int [1:2590] 0 0 0 0 0 1 0 0 0 0 ...
 $ N_HLTH    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ SN_C      : int [1:2590] 0 1 1 0 0 1 1 0 1 0 ...
 $ SN_T      : chr [1:2590] NA NA NA NA ...
 $ DLI       : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ ALI       : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ PLHSE     : int [1:2590] 0 0 0 0 0 0 1 0 0 0 ...
 $ LMILHSE   : int [1:2590] 0 0 0 0 0 1 1 0 0 0 ...
 $ ULHSE     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ EPL_ET    : int [1:2590] 0 1 0 0 0 0 0 0 0 0 ...
 $ EAL_ET    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ EBL_ET    : int [1:2590] 0 1 0 0 0 0 0 0 0 0 ...
 $ EB_ET     : int [1:2590] 0 1 0 0 0 0 0 0 0 0 ...
 $ PM25_ET   : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ DS_ET     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ TP_ET     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ LPP_ET    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ HRS_ET    : chr [1:2590] NA NA NA NA ...
 $ KP_ET     : int [1:2590] 0 0 0 0 0 0 0 0 1 0 ...
 $ HB_ET     : int [1:2590] 0 0 0 0 0 0 1 0 0 0 ...
 $ RMP_ET    : int [1:2590] 0 0 0 0 0 1 0 0 0 0 ...
 $ NPL_ET    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ TSDF_ET   : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ WD_ET     : int [1:2590] 0 0 1 0 0 1 1 0 0 0 ...
 $ UST_ET    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ DB_ET     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ A_ET      : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ HD_ET     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ LLE_ET    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ UN_ET     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ LISO_ET   : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ POV_ET    : int [1:2590] 0 0 0 0 0 0 1 0 0 0 ...
 $ LMI_ET    : int [1:2590] 0 0 0 0 0 1 1 0 0 0 ...
 $ IA_LMI_ET : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ IA_UN_ET  : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ IA_POV_ET : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ TC        : num [1:2590] 0 3 1 0 0 4 5 0 2 0 ...
 $ CC        : num [1:2590] 0 2 1 0 0 4 4 0 2 0 ...
 $ IAULHSE   : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ IAPLHSE   : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ IALMILHSE : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ IALMIL_76 : num [1:2590] NA NA NA NA NA NA NA NA NA NA ...
 $ IAPLHS_77 : num [1:2590] NA NA NA NA NA NA NA NA NA NA ...
 $ IAULHS_78 : num [1:2590] NA NA NA NA NA NA NA NA NA NA ...
 $ LHE       : int [1:2590] 1 0 1 0 1 1 1 1 1 0 ...
 $ IALHE     : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ IAHSEF    : num [1:2590] NA NA NA NA NA NA NA NA NA NA ...
 $ N_CLT_EOMI: int [1:2590] 0 1 0 0 0 1 1 0 0 0 ...
 $ N_ENY_EOMI: int [1:2590] 0 1 0 0 0 0 0 0 0 0 ...
 $ N_TRN_EOMI: int [1:2590] 0 0 0 0 0 0 0 1 1 0 ...
 $ N_HSG_EOMI: int [1:2590] 0 0 0 0 0 0 1 0 1 0 ...
 $ N_PLN_EOMI: int [1:2590] 0 0 0 0 0 1 0 0 0 0 ...
 $ N_WTR_EOMI: int [1:2590] 0 0 1 0 0 1 1 0 0 0 ...
 $ N_HLTH_88 : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
 $ N_WKFC_89 : int [1:2590] 0 0 0 0 0 1 1 0 0 0 ...
 $ FPL200S   : int [1:2590] 1 1 1 0 1 1 1 0 1 0 ...
 $ N_WKFC_91 : int [1:2590] 1 0 1 0 1 1 1 1 1 0 ...
 $ TD_ET     : int [1:2590] 0 0 0 0 0 0 0 1 1 0 ...
 $ TD_PFS    : num [1:2590] 0.67 0.78 0.6 0.63 0.85 0.35 0.29 0.94 0.91 0.78 ...
 $ FLD_PFS   : num [1:2590] 0.83 0.88 0.43 0.24 0.82 0.93 0.97 0.44 0.49 0.71 ...
 $ WFR_PFS   : num [1:2590] 0.7 0.82 0.33 0.87 0.8 0.33 0.83 0.77 0.81 0.78 ...
 $ FLD_ET    : int [1:2590] 0 0 0 0 0 1 1 0 0 0 ...
 $ WFR_ET    : int [1:2590] 0 0 0 0 0 0 0 0 0 0 ...
  [list output truncated]
 - attr(*, "sf_column")= chr "geometry"
 - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA NA NA NA NA NA ...
  ..- attr(*, "names")= chr [1:123] "GEOID10" "SF" "CF" "DF_PFS" ...

You’ll notice that this is a new data type:

sf [2,590 × 124] (S3: sf/tbl_df/tbl/data.frame)

You can read this to yourself as “cejst_shp” is an sf object with a tbl_df combined with. it. (It’s slightly more complicated than that, but this can give you an intuition).

Now let’s look at the output of glimpse:

Code
glimpse(cejst_shp)
Rows: 2,590
Columns: 124
$ GEOID10    <chr> "16019970700", "16025970100", "16027021700", "16027020700",…
$ SF         <chr> "Idaho", "Idaho", "Idaho", "Idaho", "Idaho", "Idaho", "Idah…
$ CF         <chr> "Bonneville County", "Camas County", "Canyon County", "Cany…
$ DF_PFS     <dbl> 0.44, 0.67, 0.74, 0.48, 0.75, 0.80, 0.76, 0.72, 0.76, 0.52,…
$ AF_PFS     <dbl> 0.73, 0.65, 0.86, 0.63, 0.79, 0.88, 0.86, 0.79, 0.80, 0.65,…
$ HDF_PFS    <dbl> 0.57, 0.79, 0.69, 0.47, 0.72, 0.55, 0.53, 0.71, 0.74, 0.45,…
$ DSF_PFS    <dbl> 0.53, 0.00, 0.58, 0.46, 0.12, 0.79, 0.68, 0.27, 0.06, 0.11,…
$ EBF_PFS    <dbl> 0.63, 0.95, 0.54, 0.30, 0.63, 0.81, 0.81, 0.44, 0.73, 0.52,…
$ EALR_PFS   <dbl> 0.55, 0.83, 0.63, 0.63, 0.65, NA, 0.41, 0.64, 0.65, 0.64, 0…
$ EBLR_PFS   <dbl> 0.19, 0.93, 0.05, 0.55, 0.09, 0.09, 0.08, 0.09, 0.47, 0.17,…
$ EPLR_PFS   <dbl> 0.80, 0.99, 0.09, 0.10, 0.11, 0.31, 0.08, 0.09, 0.10, 0.09,…
$ HBF_PFS    <dbl> 0.69, 0.60, 0.53, 0.07, 0.46, 0.86, 0.93, 0.22, 0.53, 0.28,…
$ LLEF_PFS   <dbl> 0.73, 0.48, 0.67, 0.29, 0.51, 0.87, 0.62, 0.38, 0.32, 0.26,…
$ LIF_PFS    <dbl> 0.54, 0.54, 0.53, 0.12, 0.48, 0.61, 0.88, 0.46, 0.41, 0.32,…
$ LMI_PFS    <dbl> 0.81, 0.75, 0.61, 0.25, 0.55, 0.92, 0.95, 0.44, 0.42, 0.35,…
$ PM25F_PFS  <dbl> 0.11, 0.00, 0.68, 0.63, 0.42, 0.66, 0.69, 0.57, 0.26, 0.40,…
$ HSEF       <dbl> 0.14, 0.06, 0.20, 0.08, 0.21, 0.24, 0.31, 0.18, 0.18, 0.09,…
$ P100_PFS   <dbl> 0.83, 0.63, 0.47, 0.24, 0.60, 0.72, 0.93, 0.27, 0.39, 0.33,…
$ P200_I_PFS <dbl> 0.86, 0.71, 0.81, 0.39, 0.75, 0.98, 0.91, 0.49, 0.67, 0.54,…
$ AJDLI_ET   <int> 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0,…
$ LPF_PFS    <dbl> 0.75, 0.52, 0.26, 0.30, 0.65, 0.62, 0.63, 0.40, 0.51, 0.36,…
$ KP_PFS     <dbl> 0.86, 0.21, 0.84, 0.21, 0.61, 0.57, 0.21, 0.43, 0.90, 0.21,…
$ NPL_PFS    <dbl> 0.09, 0.05, 0.06, 0.08, 0.03, 0.08, 0.05, 0.05, 0.08, 0.10,…
$ RMP_PFS    <dbl> 0.49, 0.01, 0.56, 0.84, 0.26, 0.96, 0.58, 0.36, 0.10, 0.20,…
$ TSDF_PFS   <dbl> 0.22, 0.01, 0.14, 0.42, 0.07, 0.55, 0.13, 0.11, 0.10, 0.19,…
$ TPF        <dbl> 5589, 1048, 11701, 3901, 5059, 4681, 3006, 7423, 6653, 4693…
$ TF_PFS     <dbl> 0.55, 0.06, 0.54, 0.53, 0.28, 0.71, 0.83, 0.24, 0.05, 0.09,…
$ UF_PFS     <dbl> 0.61, 0.16, 0.64, 0.33, 0.66, 0.86, 0.80, 0.45, 0.47, 0.61,…
$ WF_PFS     <dbl> 0.03, 0.11, 0.98, 0.24, 0.79, 0.98, 0.98, 0.85, 0.42, 0.04,…
$ UST_PFS    <dbl> 0.59, 0.02, 0.44, 0.31, 0.17, 0.73, 0.83, 0.13, 0.06, 0.18,…
$ N_WTR      <int> 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_WKFC     <int> 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_CLT      <int> 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_ENY      <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_TRN      <int> 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,…
$ N_HSG      <int> 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_PLN      <int> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_HLTH     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ SN_C       <int> 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,…
$ SN_T       <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ DLI        <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ ALI        <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ PLHSE      <int> 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ LMILHSE    <int> 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ ULHSE      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ EPL_ET     <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ EAL_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ EBL_ET     <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ EB_ET      <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ PM25_ET    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ DS_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ TP_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ LPP_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ HRS_ET     <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ KP_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0,…
$ HB_ET      <int> 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ RMP_ET     <int> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ NPL_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ TSDF_ET    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ WD_ET      <int> 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ UST_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ DB_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ A_ET       <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ HD_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ LLE_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ UN_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ LISO_ET    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ POV_ET     <int> 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ LMI_ET     <int> 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IA_LMI_ET  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IA_UN_ET   <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IA_POV_ET  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ TC         <dbl> 0, 3, 1, 0, 0, 4, 5, 0, 2, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0,…
$ CC         <dbl> 0, 2, 1, 0, 0, 4, 4, 0, 2, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0,…
$ IAULHSE    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IAPLHSE    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IALMILHSE  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IALMIL_76  <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ IAPLHS_77  <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ IAULHS_78  <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ LHE        <int> 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IALHE      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IAHSEF     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ N_CLT_EOMI <int> 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_ENY_EOMI <int> 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_TRN_EOMI <int> 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,…
$ N_HSG_EOMI <int> 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_PLN_EOMI <int> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_WTR_EOMI <int> 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_HLTH_88  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ N_WKFC_89  <int> 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ FPL200S    <int> 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,…
$ N_WKFC_91  <int> 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
$ TD_ET      <int> 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,…
$ TD_PFS     <dbl> 0.67, 0.78, 0.60, 0.63, 0.85, 0.35, 0.29, 0.94, 0.91, 0.78,…
$ FLD_PFS    <dbl> 0.83, 0.88, 0.43, 0.24, 0.82, 0.93, 0.97, 0.44, 0.49, 0.71,…
$ WFR_PFS    <dbl> 0.70, 0.82, 0.33, 0.87, 0.80, 0.33, 0.83, 0.77, 0.81, 0.78,…
$ FLD_ET     <int> 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ WFR_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ ADJ_ET     <int> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IS_PFS     <dbl> 0.64, 0.16, 0.41, 0.53, 0.86, 0.46, 0.51, 0.70, 0.82, 0.86,…
$ IS_ET      <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1,…
$ AML_ET     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ FUDS_RAW   <chr> NA, NA, NA, NA, NA, NA, NA, NA, "0", NA, NA, NA, NA, NA, NA…
$ FUDS_ET    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
$ IMP_FLG    <chr> "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",…
$ DM_B       <dbl> 0.04, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.01,…
$ DM_AI      <dbl> 0.01, 0.00, 0.01, 0.00, 0.00, 0.02, 0.01, 0.00, 0.00, 0.00,…
$ DM_A       <dbl> 0.00, 0.00, 0.00, 0.01, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
$ DM_HI      <dbl> 0.00, 0.00, 0.01, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00,…
$ DM_T       <dbl> 0.06, 0.00, 0.06, 0.04, 0.04, 0.06, 0.03, 0.01, 0.02, 0.00,…
$ DM_W       <dbl> 0.62, 0.98, 0.59, 0.88, 0.71, 0.54, 0.40, 0.81, 0.83, 0.85,…
$ DM_H       <dbl> 0.27, 0.01, 0.36, 0.07, 0.26, 0.42, 0.54, 0.16, 0.15, 0.11,…
$ DM_O       <dbl> 0.11, 0.00, 0.15, 0.02, 0.11, 0.12, 0.27, 0.03, 0.02, 0.02,…
$ AGE_10     <dbl> 0.18, 0.16, 0.15, 0.12, 0.12, 0.15, 0.17, 0.10, 0.10, 0.14,…
$ AGE_MIDDLE <dbl> 0.71, 0.65, 0.71, 0.71, 0.68, 0.77, 0.72, 0.71, 0.76, 0.66,…
$ AGE_OLD    <dbl> 0.10, 0.18, 0.13, 0.15, 0.18, 0.07, 0.09, 0.18, 0.12, 0.18,…
$ TA_COU_116 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ TA_COUNT_C <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ TA_PERC    <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ TA_PERC_FE <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ UI_EXP     <chr> "Nation", "Nation", "Nation", "Nation", "Nation", "Nation",…
$ THRHLD     <dbl> 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,…
$ geometry   <MULTIPOLYGON [°]> MULTIPOLYGON (((-112.0208 4..., MULTIPOLYGON (…

The key addition here is the geometry column. This is where the magic of tibbles comes in - it’s a list column. These sorts of columns aren’t allowed in data.frames because they entail multiple (and potentially different) data types. They become critical for spatial data (and sf objects) as they contain the coordinates for where the object need to go!

In the previous examples, you got used to checking the various columns for (in-)feasible values. You should still do this; however, the introduction of the geometry column. Identifying problematic geometry is key component of ensuring your data is valid. Luckly, you can do this with:

Code
all(st_is_valid(cejst_shp))
[1] TRUE

Things look good for now! We’ll talk more about what to do when this returns FALSE in future classes.

One final check is to take a look at the data. We’ll learn more about how to make fancy maps in the future, but for now, there’s a quick check:

Code
plot(st_geometry(cejst_shp))

Reading Data: Rasters

Let’s switch gears a bit and run through same process with rasters. Unfortunately, the terra package uses a different syntax. I’ll do my best to highlight those difference as we go, but for now, let’s focus on the terra version of read.

Code
fire_prob <- rast("data/original/inclass07/wildfire.tif")

Importantly, rast does more than just read in data. You can look at ?rast to learn some more of those functions.

Let’s look at the data with str

Code
str(fire_prob)
S4 class 'SpatRaster' [package "terra"]

You’ll notice a much less verbose response that this is a SpatRaster data class. We’ll talk more about what this means in the next few weeks, but for now, just notice that this is a distinct class assigned to a very particular package.

What happens when you look at glimpse

Code
glimpse(fire_prob)
#  A SpatRaster 4,016 x 4,607 x 1 layer (18,501,712 cells)
#  Resolution (x / y): (240 / 240)
#  Projected CRS: +proj=aea +lat_0=23 +lon_0=-96 +lat_1=29.5 +lat_2=45.5 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs
#  CRS projection units: meter <m>
#  Extent (x / y) : ([-2,294,745 / -1,189,065] , [ 2,208,735 /  3,172,575])

$ WHP_ID <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…

You get a variety of additional information on the resolution, projection, and extent. What you don’t get, however, is a geometry or any info about where each cell should be. This is because for raster data, the geometry is implicit - if we know where the raster covers, and the cell size, then we know the rest of the information necessary to derie the geometry. The other thing you’ll notice is that there’s only 1 variable. This is again a function of the raster data type. Each layer can only contain information on one measurement and all of those measurements much be of the same data class. Rasters are essentially matrices where the rows are the x coordinates, the columns are the y coordinates, and the cell values are the measurement.

The last thing we might want to do is plot the raster to quickly make sure it looks like the thing we thought it would. The nice part about terra is that there is a basic plot function that you can use:

Code
plot(fire_prob)