Date: 2025-02-10

# Get started

#### 2025-02-10

## Design

Most functions in landscapemetrics start with `lsm_` (for landscapemetrics). The second part of the name specifies the level (patch - `p`, class - `c` or landscape - `l`). The last part of the function name is the abbreviation of the corresponding metric (e.g., `enn`for the euclidean nearest-neighbor distance):

    # general structure
    lsm_"level"_"metric"

    # Patch level
    ## lsm_p_"metric"
    lsm_p_enn()

    # Class level
    ## lsm_c_"metric"
    lsm_c_enn()

    # Landscape level
    ## lsm_p_"metric"
    lsm_l_enn()

All `lsm_` functions return an identically structured tibble:

layer | level | class | id | metric | value
--- | --- | --- | --- | --- | ---
1 | patch | 1 | 1 | landscape metric | x
1 | class | 1 | NA | landscape metric | x
1 | landscape | NA | NA | landscape metric | x

## Checking your landscape

Before using landscapemetrics and calculating landscape metrics in general, it makes sense to check your landscape. If your landscape has some properties that restrict the calculation or interpretation of landscape metrics, that should be detected with `check_landscape`:

    # import raster
    # for local file: rast("pathtoyourraster/raster.asc")
    # ... or any other raster file type, geotiff, ...

    # Check your landscape
    check_landscape(landscape) # because CRS is unknown, not clear
    #> Warning: Caution: Coordinate reference system not metric - Units of results
    #> based on cellsizes and/or distances may be incorrect.
    #>   layer crs units   class n_classes OK
    #> 1     1  NA    NA integer         3 ❓

    check_landscape(podlasie_ccilc) # wrong units
    #> Warning: Caution: Coordinate reference system not metric - Units of results
    #> based on cellsizes and/or distances may be incorrect.
    #>   layer        crs   units   class n_classes OK
    #> 1     1 geographic degrees integer        14  ✖

    check_landscape(augusta_nlcd) # everything is ok
    #>   layer       crs units   class n_classes OK
    #> 1     1 projected     m integer        15  ✔

The requirements to calculate meaningful landscape metrics are:

1. The distance units of your projection are meters, as the package converts units internally and returns results in either meters, square meters or hectares. For more information see the help file of each function.
2. Your raster encodes landscape classes as integers (1, 2, 3, 4, …, n).
3. Landscape metrics describe categorical landscapes, that means that your landscape needs to be classified (we throw a warning if you have more than 30 classes to make sure you work with a classified landscape).

## Using landscapemetrics

If you are sure that your landscape is suitable for the calculation of landscape metrics, landscapemetrics makes this quite easy:

    # import raster
    # for local file: rast("pathtoyourraster/raster.asc")
    # ... or any other raster file type, geotiff, ...

    # Calculate e.g. perimeter of all patches
    lsm_p_perim(landscape)
    #> # A tibble: 28 × 6
    #>    layer level class    id metric value
    #>    <int> <chr> <int> <int> <chr>  <dbl>
    #>  1     1 patch     1     1 perim      4
    #>  2     1 patch     1     2 perim     12
    #>  3     1 patch     1     3 perim     60
    #>  4     1 patch     1     4 perim      4
    #>  5     1 patch     1     5 perim      4
    #>  6     1 patch     1     6 perim     68
    #>  7     1 patch     1     7 perim     22
    #>  8     1 patch     1     8 perim     10
    #>  9     1 patch     1     9 perim     10
    #> 10     1 patch     2    10 perim     38
    #> # ℹ 18 more rows

### Using landscapemetrics in a tidy workflow

Every function in landscapemetrics accept data as its first argument, which makes piping a natural workflow. A possible use case is that you would load your spatial data, calculate some landscape metrics and then use the resulting tibble in further analyses.

    # all patch IDs of class 2 with an ENN > 2.5
    subsample_patches <- landscape |>
        lsm_p_enn() |>
        dplyr::filter(class == 2 & value > 2.5) |>
        dplyr::pull(id)

    # show results
    subsample_patches
    #>  [1] 10 11 12 13 14 15 16 17 18 19 20 21 22

### Use multiple metric functions

To list all available metrics, just use the `list_lsm()` function. Here, you can specify, for example, a level or type of metrics.

    # list all available metrics
    list_lsm()
    #> # A tibble: 133 × 5
    #>    metric name                                type           level function_name
    #>    <chr>  <chr>                               <chr>          <chr> <chr>
    #>  1 area   patch area                          area and edge… patch lsm_p_area
    #>  2 cai    core area index                     core area met… patch lsm_p_cai
    #>  3 circle related circumscribing circle       shape metric   patch lsm_p_circle
    #>  4 contig contiguity index                    shape metric   patch lsm_p_contig
    #>  5 core   core area                           core area met… patch lsm_p_core
    #>  6 enn    euclidean nearest neighbor distance aggregation m… patch lsm_p_enn
    #>  7 frac   fractal dimension index             shape metric   patch lsm_p_frac
    #>  8 gyrate radius of gyration                  area and edge… patch lsm_p_gyrate
    #>  9 ncore  number of core areas                core area met… patch lsm_p_ncore
    #> 10 para   perimeter-area ratio                shape metric   patch lsm_p_para
    #> # ℹ 123 more rows

    # list only aggregation metrics at landscape level and just return function name
    list_lsm(level = "landscape",
             type = "aggregation metric",
             simplify = TRUE)
    #>  [1] "lsm_l_ai"       "lsm_l_cohesion" "lsm_l_contag"   "lsm_l_division"
    #>  [5] "lsm_l_enn_cv"   "lsm_l_enn_mn"   "lsm_l_enn_sd"   "lsm_l_iji"
    #>  [9] "lsm_l_lsi"      "lsm_l_mesh"     "lsm_l_np"       "lsm_l_pd"
    #> [13] "lsm_l_pladj"    "lsm_l_split"

    # you can also combine arguments and only return the function names
    list_lsm(level = c("patch", "landscape"),
             type = "core area metric",
             simplify = TRUE)
    #>  [1] "lsm_p_cai"      "lsm_p_core"     "lsm_p_ncore"    "lsm_l_cai_cv"
    #>  [5] "lsm_l_cai_mn"   "lsm_l_cai_sd"   "lsm_l_core_cv"  "lsm_l_core_mn"
    #>  [9] "lsm_l_core_sd"  "lsm_l_dcad"     "lsm_l_dcore_cv" "lsm_l_dcore_mn"
    #> [13] "lsm_l_dcore_sd" "lsm_l_ndca"     "lsm_l_tca"

Every function returns a `tibble`, thus combining the metrics that were selected for your research question is straightforward:

    # bind results from different metric functions
    patch_metrics <- dplyr::bind_rows(
      lsm_p_cai(landscape),
      lsm_p_circle(landscape),
      lsm_p_enn(landscape)
    )

    # look at the results
    patch_metrics
    #> # A tibble: 84 × 6
    #>    layer level class    id metric value
    #>    <int> <chr> <int> <int> <chr>  <dbl>
    #>  1     1 patch     1     1 cai      0
    #>  2     1 patch     1     2 cai      0
    #>  3     1 patch     1     3 cai     48.6
    #>  4     1 patch     1     4 cai      0
    #>  5     1 patch     1     5 cai      0
    #>  6     1 patch     1     6 cai     47.5
    #>  7     1 patch     1     7 cai     18.7
    #>  8     1 patch     1     8 cai      0
    #>  9     1 patch     1     9 cai      0
    #> 10     1 patch     2    10 cai     26.5
    #> # ℹ 74 more rows

All metrics are abbreviated in the result `tibble`. Therefore, we provide a `tibble` containing the full metric names, as well as the class of each metric (`lsm_abbreviations_names`). Using e.g. the `left_join()` function of the dplyr package one could join a result `tibble` and the abbreviations `tibble`.

    # bind results from different metric functions
    patch_metrics <- dplyr::bind_rows(
      lsm_p_cai(landscape),
      lsm_p_circle(landscape),
      lsm_p_enn(landscape)
      )
    # look at the results
    patch_metrics_full_names <- dplyr::left_join(x = patch_metrics,
                                                 y = lsm_abbreviations_names,
                                                 by = "metric")
    patch_metrics_full_names
    #> # A tibble: 84 × 10
    #>    layer level.x class    id metric value name       type  level.y function_name
    #>    <int> <chr>   <int> <int> <chr>  <dbl> <chr>      <chr> <chr>   <chr>
    #>  1     1 patch       1     1 cai      0   core area… core… patch   lsm_p_cai
    #>  2     1 patch       1     2 cai      0   core area… core… patch   lsm_p_cai
    #>  3     1 patch       1     3 cai     48.6 core area… core… patch   lsm_p_cai
    #>  4     1 patch       1     4 cai      0   core area… core… patch   lsm_p_cai
    #>  5     1 patch       1     5 cai      0   core area… core… patch   lsm_p_cai
    #>  6     1 patch       1     6 cai     47.5 core area… core… patch   lsm_p_cai
    #>  7     1 patch       1     7 cai     18.7 core area… core… patch   lsm_p_cai
    #>  8     1 patch       1     8 cai      0   core area… core… patch   lsm_p_cai
    #>  9     1 patch       1     9 cai      0   core area… core… patch   lsm_p_cai
    #> 10     1 patch       2    10 cai     26.5 core area… core… patch   lsm_p_cai
    #> # ℹ 74 more rows

Additionally, we provide a wrapper where the desired metrics can be specified as a vector of strings. Because all metrics regardless of the level return an identical `tibble`, different levels can be mixed. It is also possible to calculate all available metrics at a certain level using, e.g., `level = "patch"`. Additionally, similar to `list_lsm()` you can also specify, e.g., a certain group of metrics. Of course, you can also include the full names and information of all metrics using `full_name = TRUE`.

    # calculate certain metrics
    calculate_lsm(landscape,
                  what = c("lsm_c_pland", "lsm_l_ta", "lsm_l_te"))
    #> Warning: Please use 'check_landscape()' to ensure the input data is valid.
    #> # A tibble: 5 × 6
    #>   layer level     class    id metric  value
    #>   <int> <chr>     <int> <int> <chr>   <dbl>
    #> 1     1 class         1    NA pland   20.4
    #> 2     1 class         2    NA pland   26
    #> 3     1 class         3    NA pland   53.6
    #> 4     1 landscape    NA    NA ta       0.09
    #> 5     1 landscape    NA    NA te     340

    # calculate all aggregation metrics on patch and landscape level
    calculate_lsm(landscape,
                  type = "aggregation metric",
                  level = c("patch", "landscape"))
    #> Warning: Please use 'check_landscape()' to ensure the input data is valid.
    #> # A tibble: 42 × 6
    #>    layer level     class    id metric      value
    #>    <int> <chr>     <int> <int> <chr>       <dbl>
    #>  1     1 landscape    NA    NA ai       82.5
    #>  2     1 landscape    NA    NA cohesion 90.6
    #>  3     1 landscape    NA    NA contag   26.3
    #>  4     1 landscape    NA    NA division  0.896
    #>  5     1 landscape    NA    NA enn_cv   42.8
    #>  6     1 landscape    NA    NA enn_mn    3.42
    #>  7     1 landscape    NA    NA enn_sd    1.46
    #>  8     1 landscape    NA    NA iji      89.8
    #>  9     1 landscape    NA    NA lsi       3.83
    #> 10     1 landscape    NA    NA mesh      0.00938
    #> # ℹ 32 more rows

    # show full information of all metrics
    calculate_lsm(landscape,
                  what = c("lsm_c_pland", "lsm_l_ta", "lsm_l_te"),
                  full_name = TRUE)
    #> Warning: Please use 'check_landscape()' to ensure the input data is valid.
    #> # A tibble: 5 × 9
    #>   layer level     class    id metric  value name             type  function_name
    #>   <int> <chr>     <int> <int> <chr>   <dbl> <chr>            <chr> <chr>
    #> 1     1 class         1    NA pland   20.4  percentage of l… area… lsm_c_pland
    #> 2     1 class         2    NA pland   26    percentage of l… area… lsm_c_pland
    #> 3     1 class         3    NA pland   53.6  percentage of l… area… lsm_c_pland
    #> 4     1 landscape    NA    NA ta       0.09 total area       area… lsm_l_ta
    #> 5     1 landscape    NA    NA te     340    total edge       area… lsm_l_te