diff --git a/index.Rmd b/index.Rmd index 30779d2..683db89 100644 --- a/index.Rmd +++ b/index.Rmd @@ -19,7 +19,7 @@ a:visited {color: #91170a;} # [WUR Geoscripting](https://geoscripting-wur.github.io/) WUR logo -# Week 1, Tutorial 3: Intro to functions and refresher on R +# Intro to functions and refresher on R ## Learning objectives * Learn to write a function @@ -28,7 +28,11 @@ a:visited {color: #91170a;} * Use control flow for efficient function writing # Basic *R* knowledge useful for Geo-Scripting -Scripting with *R* to handle spatial problems requires a core set of basic *R* skills. To prepare you well for the coming weeks, we've summarized what we think are important skills for geoscripting below. +Scripting with *R* to handle spatial problems requires a core set of basic *R* skills. To prepare you well for the coming weeks, we've summarized what we think are important skills for geoscripting below. + +```{block type="alert alert-info"} +**Note** that this tutorial uses the basic programming structure with lists, strings, and more. For a refresher on these elements click [here](https://geoscripting-wur.github.io/RPythonBasics/). +``` ## Vector handling and vector arithmetic **In *R* we call a one-dimensional array of values a *vector*, and a two-dimensional array of values a *matrix*.** @@ -98,10 +102,10 @@ When working with real data, such as satellite imagery or KML files, the data al Key functions for handling character strings are listed below: * `list.files()`: to list files in a directory. -* `glob2rx()`: to select files using a wildcard. Note: if you know regular expressions, you do not need that function. But most people are more comfortable working with wildcards. +* `glob2rx()`: to select files using a wildcard. Note: if you know regular expressions, you do not need that function. But most people are more comfortable working with wildcards. For a list of wildcards click [here](../Intro2Linux/index.html#file-manipulation). * `paste()`, `paste0()`, `sprintf()`: useful to combine vectors e.g. to create a file name. * `strsplit()`: to split up a string. -# `switch()`: to return a value based on a match. +* `switch()`: to return a value based on a match. ### Example of `list.files()` @@ -286,7 +290,7 @@ In order to achieve these objectives, you should try to follow a few good practi - Consistent placement of curly braces. * [Make your own packages](#__optional__Writing_packages_). * Keep a similar [directory structure](../RProjectManagement/index.html) across your projects. -* Use [version control](../RProjectManagement/index.html) to develop/maintain your projects and packages. +* Use [version control](../RProjectManagement/index.html#version-control) to develop/maintain your projects and packages. * Never place `rm(list = ls())` anywhere in your script. If you do so, you may [find your computer set on fire](https://www.tidyverse.org/blog/2017/12/workflow-vs-script/). * Use relative file paths and never use `setwd()`. Do press the button below every time you open a script, and assume everyone else will do that too. @@ -369,7 +373,7 @@ More flexibility in your function can be achieved through some easy control flow Control flow refers to the use of conditions in your code that redirect the flow to different directions depending on variables values or class. Make use of that in your code, as this will make your functions more flexible and generic. ### Object classes and Control flow -You have seen in a previous tutorial already that every variable in your R working environment belongs to a class. You can take advantage of that, using control flow, to make your functions more flexible. +You have seen in a [previous tutorial](../RPythonBasics/index.html/#data-types) already that every variable in your R working environment belongs to a class. You can take advantage of that, using control flow, to make your functions more flexible. A quick reminder on classes: @@ -389,6 +393,8 @@ c <- rast(ncol = 10, nrow = 10) class(c) ``` +Here we used the function `rast` from the Terra package to create an object of class `SpatRaster`. `SpatRaster` is a class for rasters (or matrices) that comprise the necessary elements for spatial data. With Terra and `SpatRaster`, complex spatial data will be processed more efficiently by using specifically tailored functions for `SpatRaster`. This will be studied further in [another tutorial](../IntroToRaster/index.html). + ### Controlling the class of input variables of a function One way of making functions more auto-adaptive is by adding checks of the input variables. Using object class can greatly simplify this task. For example let's imagine that you just wrote a simple Hello World function. @@ -588,7 +594,7 @@ freq(a, value = -2)$count # but some elements of the list are impredictibly corrupted, so the list looks as follows b <- a c <- NA -list <- list(a, b, c) +rasterList <- list(a, b, c) # Now, b and a are SpatRasters, and c is ''corrupted'' ``` @@ -596,16 +602,16 @@ list <- list(a, b, c) ```{r, error=TRUE} # Running freq(c) would return an error and stop the whole process out <- list() -for(i in 1:length(list)) { - out[i] <- freq(list[[i]], value = -2)$count +for(i in 1:length(rasterList)) { + out[i] <- freq(rasterList[[i]], value = -2)$count } ``` ```{r} # If you wrap the call in a try(), you still get an error, but it's non-fatal out <- list() -for(i in 1:length(list)) { - out[i] <- try(freq(list[[i]], value = -2)$count) +for(i in 1:length(rasterList)) { + out[i] <- try(freq(rasterList[[i]], value = -2)$count) } out ``` @@ -624,14 +630,14 @@ fun <- function(x, value) { # Let's try to run the loop again out <- list() -for(i in 1:length(list)) { - out[i] <- fun(list[[i]], value = -2) +for(i in 1:length(rasterList)) { + out[i] <- fun(rasterList[[i]], value = -2) } out # Note that using a function of the apply family would be a more # elegant/shorter way to obtain the same result -(out <- sapply(X = list, FUN = fun, value = -2)) +(out <- sapply(X = rasterList, FUN = fun, value = -2)) ``` ### Function debugging