From a846beed0368b74b6763d179aea6325b666178fc Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 16 Oct 2024 11:39:15 +0000 Subject: [PATCH] markdown source builds Auto-generated via `{sandpaper}` Source : 781bd26020091075ad893b9f1928e9af71fc39fa Branch : main Author : Toby Hodges Time : 2024-10-16 11:34:04 +0000 Message : Merge pull request #155 from datacarpentry/update-lockfile-oct2024 Update dependencies --- 01-rstudio-intro.md | 106 +- 03-data-structures-part1.md | 286 ++--- 04-data-structures-part2.md | 118 +- 05-data-subsetting.md | 148 +-- 06-dplyr.md | 72 +- 07-plot-ggplot2.md | 22 +- 08-writing-data.md | 12 +- config.yaml | 88 -- ...07-plot-ggplot2-rendered-gpd-per-cap-1.png | Bin 9828 -> 9823 bytes md5sum.txt | 36 +- renv.lock | 1072 ----------------- 11 files changed, 399 insertions(+), 1561 deletions(-) delete mode 100644 config.yaml delete mode 100644 renv.lock diff --git a/01-rstudio-intro.md b/01-rstudio-intro.md index 6d865aefe..343d8e2c8 100644 --- a/01-rstudio-intro.md +++ b/01-rstudio-intro.md @@ -175,11 +175,11 @@ attempt to execute them, and then returns a result. The simplest thing you could do with R is do arithmetic: -```r +``` r 1 + 100 ``` -```{.output} +``` output [1] 101 ``` @@ -230,11 +230,11 @@ From highest to lowest precedence: - Subtract: `-` -```r +``` r 3 + 5 * 2 ``` -```{.output} +``` output [1] 13 ``` @@ -243,11 +243,11 @@ evaluation if it differs from the default, or to make clear what you intend. -```r +``` r (3 + 5) * 2 ``` -```{.output} +``` output [1] 16 ``` @@ -255,7 +255,7 @@ This can get unwieldy when not needed, but clarifies your intentions. Remember that others may later read your code. -```r +``` r (3 + (5 * (2 ^ 2))) # hard to read 3 + 5 * 2 ^ 2 # clear, if you remember the rules 3 + 5 * (2 ^ 2) # if you forget some rules, this might help @@ -268,11 +268,11 @@ The text after each line of code is called a Really small or large numbers get a scientific notation: -```r +``` r 2/10000 ``` -```{.output} +``` output [1] 2e-04 ``` @@ -282,11 +282,11 @@ is shorthand for `2 * 10^(-4)`. You can write numbers in scientific notation too: -```r +``` r 5e3 # Note the lack of minus here ``` -```{.output} +``` output [1] 5000 ``` @@ -309,56 +309,56 @@ later. We can also do comparison in R: -```r +``` r 1 == 1 # equality (note two equals signs, read as "is equal to") ``` -```{.output} +``` output [1] TRUE ``` -```r +``` r 1 != 2 # inequality (read as "is not equal to") ``` -```{.output} +``` output [1] TRUE ``` -```r +``` r 1 < 2 # less than ``` -```{.output} +``` output [1] TRUE ``` -```r +``` r 1 <= 1 # less than or equal to ``` -```{.output} +``` output [1] TRUE ``` -```r +``` r 1 > 0 # greater than ``` -```{.output} +``` output [1] TRUE ``` -```r +``` r 1 >= -9 # greater than or equal to ``` -```{.output} +``` output [1] TRUE ``` @@ -389,7 +389,7 @@ Further reading: [http://floating-point-gui.de/](https://floating-point-gui.de/) We can store values in variables using the assignment operator `<-`, like this: -```r +``` r x <- 1/40 ``` @@ -397,11 +397,11 @@ Notice that assignment does not print a value. Instead, we stored it for later in something called a **variable**. `x` now contains the **value** `0.025`: -```r +``` r x ``` -```{.output} +``` output [1] 0.025 ``` @@ -412,18 +412,18 @@ Look for the `Environment` tab in one of the panes of RStudio, and you will see have appeared. Our variable `x` can be used in place of a number in any calculation that expects a number: -```r +``` r log(x) ``` -```{.output} +``` output [1] -3.688879 ``` Notice also that variables can be reassigned: -```r +``` r x <- 100 ``` @@ -432,7 +432,7 @@ x <- 100 Assignment values can contain the variable being assigned to: -```r +``` r x <- x + 1 #notice how RStudio updates its description of x on the top right tab y <- x * 2 ``` @@ -448,7 +448,7 @@ What will be the value of each variable after each statement in the following program? -```r +``` r mass <- 47.5 age <- 122 mass <- mass * 2.3 @@ -460,21 +460,21 @@ age <- age - 20 ## Solution to challenge 1 -```r +``` r mass <- 47.5 ``` This will give a value of 47.5 for the variable mass -```r +``` r age <- 122 ``` This will give a value of 122 for the variable age -```r +``` r mass <- mass * 2.3 ``` @@ -482,7 +482,7 @@ This will multiply the existing value of 47.5 by 2.3 to give a new value of 109.25 to the variable mass. -```r +``` r age <- age - 20 ``` @@ -509,11 +509,11 @@ compare mass to age. Is mass larger than age? One way of answering this question in R is to use the `>` to set up the following: -```r +``` r mass > age ``` -```{.output} +``` output [1] TRUE ``` @@ -538,7 +538,7 @@ What you use is up to you, but **be consistent**. It is also possible to use the `=` operator for assignment: -```r +``` r x = 1/40 ``` @@ -554,7 +554,7 @@ symbol used in the community. So the recommendation is to use `<-`. Which of the following are valid R variable names? -```r +``` r min_height max.height _age @@ -572,7 +572,7 @@ celsius2kelvin The following can be used as R variables: -```r +``` r min_height max.height MaxLength @@ -582,7 +582,7 @@ celsius2kelvin The following creates a hidden variable: -```r +``` r .mass ``` @@ -592,7 +592,7 @@ beginning of variable names unless you intend your variables to be hidden. The following will not be able to be used to create a variable -```r +``` r _age min-length 2widths @@ -617,20 +617,18 @@ There are two main ways to install packages in R: 2. We can use the `install.packages( )` function. We can do this to install the `dplyr` R package. -```r +``` r install.packages("dplyr") ``` -```{.output} +``` output The following package(s) will be installed: - dplyr [1.1.4] -- vctrs [0.6.5] -These packages will be installed into "~/work/r-intro-geospatial/r-intro-geospatial/renv/profiles/lesson-requirements/renv/library/R-4.3/x86_64-pc-linux-gnu". +These packages will be installed into "~/work/r-intro-geospatial/r-intro-geospatial/renv/profiles/lesson-requirements/renv/library/linux-ubuntu-jammy/R-4.4/x86_64-pc-linux-gnu". # Installing packages -------------------------------------------------------- -- Installing vctrs ... OK [linked from cache] - Installing dplyr ... OK [linked from cache] -Successfully installed 2 packages in 9.1 milliseconds. +Successfully installed 1 package in 6.5 milliseconds. ``` It's important to note that we only need to install the R package on our computer once. Well, if we install a new version of R on the same computer, then we will likely need to also re-install the R packages too. @@ -648,7 +646,7 @@ What code would we use to install the `ggplot2` package? We would use the following R code to install the `ggplot2` package: -```r +``` r install.packages("ggplot2") ``` @@ -661,22 +659,22 @@ Now that we've installed the R package, we're ready to use it! To use the R pack To load an R package, we use the `library( )` function. We can load the `dplyr` package like this: -```r +``` r library(dplyr) ``` -```{.output} +``` output Attaching package: 'dplyr' ``` -```{.output} +``` output The following objects are masked from 'package:stats': filter, lag ``` -```{.output} +``` output The following objects are masked from 'package:base': intersect, setdiff, setequal, union @@ -706,7 +704,7 @@ Answer d will produce an error because ggplot2 is misspelled. Note: It is more common for coders to *not use quotation* marks when loading an R package (i.e., answer c). -```r +``` r library(ggplot2) ``` diff --git a/03-data-structures-part1.md b/03-data-structures-part1.md index 1ff7611fd..c72cb595e 100644 --- a/03-data-structures-part1.md +++ b/03-data-structures-part1.md @@ -29,7 +29,7 @@ downloading and reading in a file `nordic-data.csv`. We will save this data as an object named `nordic`: -```r +``` r nordic <- read.csv("data/nordic-data.csv") ``` @@ -47,41 +47,41 @@ We can begin exploring our dataset right away, pulling out columns by specifying them using the `$` operator: -```r +``` r nordic$country ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` -```r +``` r nordic$lifeExp ``` -```{.output} +``` output [1] 77.2 80.0 79.0 ``` We can do other operations on the columns. For example, if we discovered that the life expectancy is two years higher: -```r +``` r nordic$lifeExp + 2 ``` -```{.output} +``` output [1] 79.2 82.0 81.0 ``` But what about: -```r +``` r nordic$lifeExp + nordic$country ``` -```{.error} +``` error Error in nordic$lifeExp + nordic$country: non-numeric argument to binary operator ``` @@ -104,62 +104,62 @@ important concept in programming called *data classes*. We can ask what class of data something is: -```r +``` r class(nordic$lifeExp) ``` -```{.output} +``` output [1] "numeric" ``` There are 6 main types: `numeric`, `integer`, `complex`, `logical`, `character`, and `factor`. -```r +``` r class(3.14) ``` -```{.output} +``` output [1] "numeric" ``` -```r +``` r class(1L) # The L suffix forces the number to be an integer, since by default R uses float numbers ``` -```{.output} +``` output [1] "integer" ``` -```r +``` r class(1+1i) ``` -```{.output} +``` output [1] "complex" ``` -```r +``` r class(TRUE) ``` -```{.output} +``` output [1] "logical" ``` -```r +``` r class('banana') ``` -```{.output} +``` output [1] "character" ``` -```r +``` r class(factor('banana')) ``` -```{.output} +``` output [1] "factor" ``` @@ -174,12 +174,12 @@ Load the new nordic data as `nordic_2`, and check what class of data we find in `lifeExp` column: -```r +``` r nordic_2 <- read.csv("data/nordic-data-2.csv") class(nordic_2$lifeExp) ``` -```{.output} +``` output [1] "character" ``` @@ -187,11 +187,11 @@ Oh no, our life expectancy lifeExp aren't the numeric type anymore! If we try to we did on them before, we run into trouble: -```r +``` r nordic_2$lifeExp + 2 ``` -```{.error} +``` error Error in nordic_2$lifeExp + 2: non-numeric argument to binary operator ``` @@ -205,11 +205,11 @@ data types. We can see that it is a dataframe by calling the `class()` function on it: -```r +``` r class(nordic) ``` -```{.output} +``` output [1] "data.frame" ``` @@ -222,12 +222,12 @@ To better understand this behavior, let's meet another of the data structures: the vector. -```r +``` r my_vector <- vector(length = 3) my_vector ``` -```{.output} +``` output [1] FALSE FALSE FALSE ``` @@ -237,23 +237,23 @@ you don't choose the data type, it'll default to `logical`; or, you can declare an empty vector of whatever type you like. -```r +``` r another_vector <- vector(mode = 'character', length = 3) another_vector ``` -```{.output} +``` output [1] "" "" "" ``` You can check if something is a vector: -```r +``` r str(another_vector) ``` -```{.output} +``` output chr [1:3] "" "" "" ``` @@ -264,11 +264,11 @@ case `[1:3]`; and a few examples of what's actually in the vector - in this case empty character strings. If we similarly do -```r +``` r str(nordic$lifeExp) ``` -```{.output} +``` output num [1:3] 77.2 80 79 ``` @@ -303,19 +303,19 @@ our lives easier in R. You can also make vectors with explicit contents with the combine function: -```r +``` r combine_vector <- c(2, 6, 3) combine_vector ``` -```{.output} +``` output [1] 2 6 3 ``` Given what we've learned so far, what do you think the following will produce? -```r +``` r quiz_vector <- c(2, 6, '3') ``` @@ -326,21 +326,21 @@ be combined into a single vector, it will force them all to be the same type. Consider: -```r +``` r coercion_vector <- c('a', TRUE) coercion_vector ``` -```{.output} +``` output [1] "a" "TRUE" ``` -```r +``` r another_coercion_vector <- c(0, TRUE) another_coercion_vector ``` -```{.output} +``` output [1] 0 1 ``` @@ -349,30 +349,30 @@ The coercion rules go: `logical` -> `integer` -> `numeric` -> `complex` -> force coercion against this flow using the `as.` functions: -```r +``` r character_vector_example <- c('0', '2', '4') character_vector_example ``` -```{.output} +``` output [1] "0" "2" "4" ``` -```r +``` r character_coerced_to_numeric <- as.numeric(character_vector_example) character_coerced_to_numeric ``` -```{.output} +``` output [1] 0 2 4 ``` -```r +``` r numeric_coerced_to_logical <- as.logical(character_coerced_to_numeric) numeric_coerced_to_logical ``` -```{.output} +``` output [1] FALSE TRUE TRUE ``` @@ -395,19 +395,19 @@ these columns different classes? ## Solution -```r +``` r str(nordic_2$lifeExp) ``` -```{.output} +``` output chr [1:3] "77.2" "80" "79.0 or 83" ``` -```r +``` r str(nordic$lifeExp) ``` -```{.output} +``` output num [1:3] 77.2 80 79 ``` @@ -422,49 +422,49 @@ data point. The combine function, `c()`, will also append things to an existing vector: -```r +``` r ab_vector <- c('a', 'b') ab_vector ``` -```{.output} +``` output [1] "a" "b" ``` -```r +``` r combine_example <- c(ab_vector, 'DC') combine_example ``` -```{.output} +``` output [1] "a" "b" "DC" ``` You can also make series of numbers: -```r +``` r my_series <- 1:10 my_series ``` -```{.output} +``` output [1] 1 2 3 4 5 6 7 8 9 10 ``` -```r +``` r seq(10) ``` -```{.output} +``` output [1] 1 2 3 4 5 6 7 8 9 10 ``` -```r +``` r seq(1,10, by = 0.1) ``` -```{.output} +``` output [1] 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 [16] 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 [31] 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 @@ -477,58 +477,58 @@ seq(1,10, by = 0.1) We can ask a few questions about vectors: -```r +``` r sequence_example <- seq(10) head(sequence_example,n = 2) ``` -```{.output} +``` output [1] 1 2 ``` -```r +``` r tail(sequence_example, n = 4) ``` -```{.output} +``` output [1] 7 8 9 10 ``` -```r +``` r length(sequence_example) ``` -```{.output} +``` output [1] 10 ``` -```r +``` r class(sequence_example) ``` -```{.output} +``` output [1] "integer" ``` Finally, you can give names to elements in your vector: -```r +``` r my_example <- 5:8 names(my_example) <- c("a", "b", "c", "d") my_example ``` -```{.output} +``` output a b c d 5 6 7 8 ``` -```r +``` r names(my_example) ``` -```{.output} +``` output [1] "a" "b" "c" "d" ``` @@ -545,7 +545,7 @@ names A through Z (hint: there is a built in vector called `LETTERS`) ## Solution to Challenge 2 -```r +``` r x <- 1:26 x <- x * 2 names(x) <- LETTERS @@ -560,27 +560,27 @@ names(x) <- LETTERS We said that columns in data frames were vectors: -```r +``` r str(nordic$lifeExp) ``` -```{.output} +``` output num [1:3] 77.2 80 79 ``` -```r +``` r str(nordic$year) ``` -```{.output} +``` output int [1:3] 2002 2002 2002 ``` -```r +``` r str(nordic$country) ``` -```{.output} +``` output chr [1:3] "Denmark" "Sweden" "Norway" ``` @@ -594,40 +594,40 @@ For example, let's make a vector of strings labeling nordic countries for all the countries in our study: -```r +``` r nordic_countries <- c('Norway', 'Finland', 'Denmark', 'Iceland', 'Sweden') nordic_countries ``` -```{.output} +``` output [1] "Norway" "Finland" "Denmark" "Iceland" "Sweden" ``` -```r +``` r str(nordic_countries) ``` -```{.output} +``` output chr [1:5] "Norway" "Finland" "Denmark" "Iceland" "Sweden" ``` We can turn a vector into a factor like so: -```r +``` r categories <- factor(nordic_countries) class(categories) ``` -```{.output} +``` output [1] "factor" ``` -```r +``` r str(categories) ``` -```{.output} +``` output Factor w/ 5 levels "Denmark","Finland",..: 4 2 1 3 5 ``` @@ -638,19 +638,19 @@ with numbered indices under the hood, this is necessary as many statistical calculations utilise such numerical representations for categorical data: -```r +``` r class(nordic_countries) ``` -```{.output} +``` output [1] "character" ``` -```r +``` r class(categories) ``` -```{.output} +``` output [1] "factor" ``` @@ -691,12 +691,12 @@ Converting character vectors to factors can be done using the `factor()` function: -```r +``` r nordic$country <- factor(nordic$country) nordic$country ``` -```{.output} +``` output [1] Denmark Sweden Norway Levels: Denmark Norway Sweden ``` @@ -704,24 +704,24 @@ Levels: Denmark Norway Sweden You can convert these back to character vectors using `as.character()`: -```r +``` r nordic$country <- as.character(nordic$country) nordic$country ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` You can convert numeric vectors to factors in the exact same way: -```r +``` r nordic$lifeExp <- factor(nordic$lifeExp) nordic$lifeExp ``` -```{.output} +``` output [1] 77.2 80 79 Levels: 77.2 79 80 ``` @@ -729,11 +729,11 @@ Levels: 77.2 79 80 But be careful -- you can't use `as.numeric()` to convert factors to numerics! -```r +``` r as.numeric(nordic$lifeExp) ``` -```{.output} +``` output [1] 1 3 2 ``` @@ -742,13 +742,13 @@ talked about. To go from a factor to a number, you need to first turn the factor into a character vector, and _then_ turn that into a numeric vector: -```r +``` r nordic$lifeExp <- as.character(nordic$lifeExp) nordic$lifeExp <- as.numeric(nordic$lifeExp) nordic$lifeExp ``` -```{.output} +``` output [1] 77.2 80.0 79.0 ``` @@ -765,13 +765,13 @@ levels are. This is assumed to be the first factor, but by default factors are labeled in alphabetical order. You can change this by specifying the levels: -```r +``` r mydata <- c("case", "control", "control", "case") factor_ordering_example <- factor(mydata, levels = c("control", "case")) str(factor_ordering_example) ``` -```{.output} +``` output Factor w/ 2 levels "control","case": 2 1 1 2 ``` @@ -786,12 +786,12 @@ is simpler in some ways than the other types, because you can put anything you want in it: -```r +``` r list_example <- list(1, "a", TRUE, c(2, 6, 7)) list_example ``` -```{.output} +``` output [[1]] [1] 1 @@ -805,12 +805,12 @@ list_example [1] 2 6 7 ``` -```r +``` r another_list <- list(title = "Numbers", numbers = 1:10, data = TRUE ) another_list ``` -```{.output} +``` output $title [1] "Numbers" @@ -824,22 +824,22 @@ $data We can now understand something a bit surprising in our data frame; what happens if we compare `str(nordic)` and `str(another_list)`: -```r +``` r str(nordic) ``` -```{.output} +``` output 'data.frame': 3 obs. of 3 variables: $ country: chr "Denmark" "Sweden" "Norway" $ year : int 2002 2002 2002 $ lifeExp: num 77.2 80 79 ``` -```r +``` r str(another_list) ``` -```{.output} +``` output List of 3 $ title : chr "Numbers" $ numbers: int [1:10] 1 2 3 4 5 6 7 8 9 10 @@ -853,35 +853,35 @@ In our `nordic` example, we have an integer, a double and a logical variable. As we have seen already, each column of data frame is a vector. -```r +``` r nordic$country ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` -```r +``` r nordic[, 1] ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` -```r +``` r class(nordic[, 1]) ``` -```{.output} +``` output [1] "character" ``` -```r +``` r str(nordic[, 1]) ``` -```{.output} +``` output chr [1:3] "Denmark" "Sweden" "Norway" ``` @@ -889,28 +889,28 @@ Each row is an *observation* of different variables, itself a data frame, and thus can be composed of elements of different types. -```r +``` r nordic[1, ] ``` -```{.output} +``` output country year lifeExp 1 Denmark 2002 77.2 ``` -```r +``` r class(nordic[1, ]) ``` -```{.output} +``` output [1] "data.frame" ``` -```r +``` r str(nordic[1, ]) ``` -```{.output} +``` output 'data.frame': 1 obs. of 3 variables: $ country: chr "Denmark" $ year : int 2002 @@ -941,11 +941,11 @@ Try out these examples and explain what is returned by each one. ## Solution to Challenge 4 -```r +``` r nordic[1] ``` -```{.output} +``` output country 1 Denmark 2 Sweden @@ -957,11 +957,11 @@ returns the first slice of the list, as another list. In this case it is the first column of the data frame. -```r +``` r nordic[[1]] ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` @@ -969,11 +969,11 @@ The double brace `[[1]]` returns the contents of the list item. In this case it is the contents of the first column, a *vector* of type *character*. -```r +``` r nordic$country ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` @@ -981,11 +981,11 @@ This example uses the `$` character to address items by name. *country* is the first column of the data frame, again a *vector* of type *character*. -```r +``` r nordic["country"] ``` -```{.output} +``` output country 1 Denmark 2 Sweden @@ -996,11 +996,11 @@ Here we are using a single brace `["country"]` replacing the index number with the column name. Like example 1, the returned object is a *list*. -```r +``` r nordic[1, 1] ``` -```{.output} +``` output [1] "Denmark" ``` @@ -1009,11 +1009,11 @@ coordinates. The returned object is the value in row 1, column 1. The object is an *character*: the first value of the first vector in our `nordic` object. -```r +``` r nordic[, 1] ``` -```{.output} +``` output [1] "Denmark" "Sweden" "Norway" ``` @@ -1022,11 +1022,11 @@ coordinates. The row coordinate is not specified, R interprets this missing value as all the elements in this *column* *vector*. -```r +``` r nordic[1, ] ``` -```{.output} +``` output country year lifeExp 1 Denmark 2002 77.2 ``` diff --git a/04-data-structures-part2.md b/04-data-structures-part2.md index aea558229..8fd1b9a55 100644 --- a/04-data-structures-part2.md +++ b/04-data-structures-part2.md @@ -42,7 +42,7 @@ examples in this episode. ::::::::::::::::::::::::::::::::::::::::: -```r +``` r gapminder <- read.csv("data/gapminder_data.csv") ``` @@ -59,7 +59,7 @@ gapminder <- read.csv("data/gapminder_data.csv") download location, for example, -```r +``` r download.file("https://datacarpentry.org/r-intro-geospatial/data/gapminder_data.csv", destfile = "data/gapminder_data.csv") gapminder <- read.csv("data/gapminder_data.csv") @@ -71,7 +71,7 @@ gapminder <- read.csv("data/gapminder_data.csv") your computer. For example, -```r +``` r gapminder <- read.csv("https://datacarpentry.org/r-intro-geospatial/data/gapminder_data.csv", stringsAsFactors = TRUE) #in R version 4.0.0 the default stringsAsFactors changed from TRUE to FALSE. But because below we use some examples to show what is a factor, we need to add the stringAsFactors = TRUE to be able to perform the below examples with factor. ``` @@ -85,11 +85,11 @@ Let's investigate the `gapminder` data frame a bit; the first thing we should always do is check out what the data looks like with `str`: -```r +``` r str(gapminder) ``` -```{.output} +``` output 'data.frame': 1704 obs. of 6 variables: $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... @@ -102,27 +102,27 @@ str(gapminder) We can also examine individual columns of the data frame with our `class` function: -```r +``` r class(gapminder$year) ``` -```{.output} +``` output [1] "integer" ``` -```r +``` r class(gapminder$country) ``` -```{.output} +``` output [1] "character" ``` -```r +``` r str(gapminder$country) ``` -```{.output} +``` output chr [1:1704] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... ``` @@ -131,7 +131,7 @@ remembering that `str(gapminder)` said there were 1704 observations of 6 variables in gapminder, what do you think the following will produce, and why? -```r +``` r length(gapminder) ``` @@ -139,41 +139,41 @@ A fair guess would have been to say that the length of a data frame would be the number of rows it has (1704), but this is not the case; it gives us the number of columns. -```r +``` r class(gapminder) ``` -```{.output} +``` output [1] "data.frame" ``` To get the number of rows and columns in our dataset, try: -```r +``` r nrow(gapminder) ``` -```{.output} +``` output [1] 1704 ``` -```r +``` r ncol(gapminder) ``` -```{.output} +``` output [1] 6 ``` Or, both at once: -```r +``` r dim(gapminder) ``` -```{.output} +``` output [1] 1704 6 ``` @@ -181,11 +181,11 @@ We'll also likely want to know what the titles of all the columns are, so we can ask for them later: -```r +``` r colnames(gapminder) ``` -```{.output} +``` output [1] "country" "year" "pop" "continent" "lifeExp" "gdpPercap" ``` @@ -200,11 +200,11 @@ Once we're happy that the data types and structures seem reasonable, it's time to start digging into our data proper. Check out the first few lines: -```r +``` r head(gapminder) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 @@ -232,7 +232,7 @@ To check the last few lines it's relatively simple as R already has a function for this: -```r +``` r tail(gapminder) tail(gapminder, n = 15) ``` @@ -254,7 +254,7 @@ function for this. What about getting a (pseudorandom) sample? R also has a function for this. -```r +``` r gapminder[sample(nrow(gapminder), 5), ] ``` @@ -291,12 +291,12 @@ The object `gapminder` is a data frame with columns We would like to create a new column to hold information on whether the life expectancy is below the world average life expectancy (70.5) or above: -```r +``` r below_average <- gapminder$lifeExp < 70.5 head(gapminder) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 @@ -309,12 +309,12 @@ head(gapminder) We can then add this as a column via: -```r +``` r cbind(gapminder, below_average) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 TRUE 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 TRUE @@ -329,11 +329,11 @@ let's put our `cbind` command within a call to `head` to return only the first six lines of the output. -```r +``` r head(cbind(gapminder, below_average)) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 TRUE 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 TRUE @@ -346,12 +346,12 @@ head(cbind(gapminder, below_average)) Note that if we tried to add a vector of `below_average` with a different number of entries than the number of rows in the dataframe, it would fail: -```r +``` r below_average <- c(TRUE, TRUE, TRUE, TRUE, TRUE) head(cbind(gapminder, below_average)) ``` -```{.error} +``` error Error in data.frame(..., check.names = FALSE): arguments imply differing number of rows: 1704, 5 ``` @@ -359,31 +359,31 @@ Why didn't this work? R wants to see one element in our new column for every row in the table: -```r +``` r nrow(gapminder) ``` -```{.output} +``` output [1] 1704 ``` -```r +``` r length(below_average) ``` -```{.output} +``` output [1] 5 ``` So for it to work we need either to have `nrow(gapminder)` = `length(below_average)` or `nrow(gapminder)` to be a multiple of `length(below_average)`: -```r +``` r below_average <- c(TRUE, TRUE, FALSE) head(cbind(gapminder, below_average)) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 TRUE 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 TRUE @@ -398,7 +398,7 @@ The sequence `TRUE,TRUE,FALSE` is repeated over all the gapminder rows. Let's overwrite the content of gapminder with our new data frame. -```r +``` r below_average <- as.logical(gapminder$lifeExp<70.5) gapminder <- cbind(gapminder, below_average) ``` @@ -406,13 +406,13 @@ gapminder <- cbind(gapminder, below_average) Now how about adding rows? The rows of a data frame are lists: -```r +``` r new_row <- list('Norway', 2016, 5000000, 'Nordic', 80.3, 49400.0, FALSE) gapminder_norway <- rbind(gapminder, new_row) tail(gapminder_norway) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 1700 Zimbabwe 1987 9216418 Africa 62.351 706.1573 TRUE 1701 Zimbabwe 1992 10704340 Africa 60.377 693.4208 TRUE @@ -442,30 +442,30 @@ add a gapminder row with a "Nordic" *continent*, add "Nordic" as a *level* of the factor: -```r +``` r levels(gapminder$continent) ``` -```{.output} +``` output NULL ``` -```r +``` r levels(gapminder$continent) <- c(levels(gapminder$continent), "Nordic") gapminder_norway <- rbind(gapminder, list('Norway', 2016, 5000000, 'Nordic', 80.3,49400.0, FALSE)) ``` -```{.warning} +``` warning Warning in `[<-.factor`(`*tmp*`, ri, value = structure(c("Asia", "Asia", : invalid factor level, NA generated ``` -```r +``` r tail(gapminder_norway) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 1700 Zimbabwe 1987 9216418 62.351 706.1573 TRUE 1701 Zimbabwe 1992 10704340 60.377 693.4208 TRUE @@ -480,11 +480,11 @@ categories of the factor, but we can subsequently add any word we want to the column without babysitting the factor levels: -```r +``` r str(gapminder) ``` -```{.output} +``` output 'data.frame': 1704 obs. of 7 variables: $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... @@ -496,12 +496,12 @@ str(gapminder) $ below_average: logi TRUE TRUE TRUE TRUE TRUE TRUE ... ``` -```r +``` r gapminder$continent <- as.character(gapminder$continent) str(gapminder) ``` -```{.output} +``` output 'data.frame': 1704 obs. of 7 variables: $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... @@ -519,12 +519,12 @@ vectors and rows are lists.* We can also glue two data frames together with `rbind`: -```r +``` r gapminder <- rbind(gapminder, gapminder) tail(gapminder, n=3) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 3406 Zimbabwe 1997 11404948 Africa 46.809 792.4500 TRUE 3407 Zimbabwe 2002 11926563 Africa 39.989 672.0386 TRUE @@ -535,12 +535,12 @@ But now the row names are unnecessarily complicated (not consecutive numbers). We can remove the rownames, and R will automatically re-name them sequentially: -```r +``` r rownames(gapminder) <- NULL head(gapminder) ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap below_average 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 TRUE 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 TRUE @@ -557,7 +557,7 @@ head(gapminder) You can create a new data frame right from within R with the following syntax: -```r +``` r df <- data.frame(id = c("a", "b", "c"), x = 1:3, y = c(TRUE, TRUE, FALSE)) @@ -578,7 +578,7 @@ time for coffee break?" ## Solution to Challenge 3 -```r +``` r df <- data.frame(first = c("Grace"), last = c("Hopper"), lucky_number = c(0)) diff --git a/05-data-subsetting.md b/05-data-subsetting.md index 9b48a56e3..70ec696cc 100644 --- a/05-data-subsetting.md +++ b/05-data-subsetting.md @@ -30,13 +30,13 @@ different subsetting operators for the different data structures. Let's start with the workhorse of R: a simple numeric vector. -```r +``` r x <- c(5.4, 6.2, 7.1, 4.8, 7.5) names(x) <- c('a', 'b', 'c', 'd', 'e') x ``` -```{.output} +``` output a b c d e 5.4 6.2 7.1 4.8 7.5 ``` @@ -60,21 +60,21 @@ To extract elements of a vector we can give their corresponding index, starting from one: -```r +``` r x[1] ``` -```{.output} +``` output a 5.4 ``` -```r +``` r x[4] ``` -```{.output} +``` output d 4.8 ``` @@ -85,11 +85,11 @@ It may look different, but the square brackets operator is a function. For vecto We can ask for multiple elements at once: -```r +``` r x[c(1, 3)] ``` -```{.output} +``` output a c 5.4 7.1 ``` @@ -97,11 +97,11 @@ x[c(1, 3)] Or slices of the vector: -```r +``` r x[1:4] ``` -```{.output} +``` output a b c d 5.4 6.2 7.1 4.8 ``` @@ -109,30 +109,30 @@ x[1:4] the `:` operator creates a sequence of numbers from the left element to the right. -```r +``` r 1:4 ``` -```{.output} +``` output [1] 1 2 3 4 ``` -```r +``` r c(1, 2, 3, 4) ``` -```{.output} +``` output [1] 1 2 3 4 ``` We can ask for the same element multiple times: -```r +``` r x[c(1, 1, 3)] ``` -```{.output} +``` output a a c 5.4 5.4 7.1 ``` @@ -140,11 +140,11 @@ x[c(1, 1, 3)] If we ask for an index beyond the length of the vector, R will return a missing value: -```r +``` r x[6] ``` -```{.output} +``` output NA ``` @@ -154,11 +154,11 @@ This is a vector of length one containing an `NA`, whose name is also `NA`. If we ask for the 0th element, we get an empty vector: -```r +``` r x[0] ``` -```{.output} +``` output named numeric(0) ``` @@ -178,11 +178,11 @@ If we use a negative number as the index of a vector, R will return every element *except* for the one specified: -```r +``` r x[-2] ``` -```{.output} +``` output a c d e 5.4 7.1 4.8 7.5 ``` @@ -190,11 +190,11 @@ x[-2] We can skip multiple elements: -```r +``` r x[c(-1, -5)] # or x[-c(1,5)] ``` -```{.output} +``` output b c d 6.2 7.1 4.8 ``` @@ -208,14 +208,14 @@ slices of a vector. It's natural to to try to negate a sequence like so: -```r +``` r x[-1:3] ``` This gives a somewhat cryptic error: -```{.error} +``` error Error in x[-1:3]: only 0's may be mixed with negative subscripts ``` @@ -227,11 +227,11 @@ The correct solution is to wrap that function call in brackets, so that the `-` operator applies to the result: -```r +``` r x[-(1:3)] ``` -```{.output} +``` output d e 4.8 7.5 ``` @@ -242,12 +242,12 @@ To remove elements from a vector, we need to assign the result back into the variable: -```r +``` r x <- x[-4] x ``` -```{.output} +``` output a b c e 5.4 6.2 7.1 7.5 ``` @@ -259,13 +259,13 @@ x Given the following code: -```r +``` r x <- c(5.4, 6.2, 7.1, 4.8, 7.5) names(x) <- c('a', 'b', 'c', 'd', 'e') print(x) ``` -```{.output} +``` output a b c d e 5.4 6.2 7.1 4.8 7.5 ``` @@ -273,7 +273,7 @@ print(x) Come up with at least 3 different commands that will produce the following output: -```{.output} +``` output b c d 6.2 7.1 4.8 ``` @@ -285,41 +285,41 @@ After you find 3 different commands, compare notes with your neighbour. Did you ## Solution to challenge 1 -```r +``` r x[2:4] ``` -```{.output} +``` output b c d 6.2 7.1 4.8 ``` -```r +``` r x[-c(1,5)] ``` -```{.output} +``` output b c d 6.2 7.1 4.8 ``` -```r +``` r x[c("b", "c", "d")] ``` -```{.output} +``` output b c d 6.2 7.1 4.8 ``` -```r +``` r x[c(2,3,4)] ``` -```{.output} +``` output b c d 6.2 7.1 4.8 ``` @@ -333,12 +333,12 @@ x[c(2,3,4)] We can extract elements by using their name, instead of extracting by index: -```r +``` r x <- c(a = 5.4, b = 6.2, c = 7.1, d = 4.8, e = 7.5) # we can name a vector 'on the fly' x[c("a", "c")] ``` -```{.output} +``` output a c 5.4 7.1 ``` @@ -352,11 +352,11 @@ subsetting operations, but the names will always remain the same! We can also use any logical vector to subset: -```r +``` r x[c(FALSE, FALSE, TRUE, FALSE, TRUE)] ``` -```{.output} +``` output c e 7.1 7.5 ``` @@ -366,11 +366,11 @@ use them to succinctly subset vectors: the following statement gives the same result as the previous one. -```r +``` r x[x > 7] ``` -```{.output} +``` output c e 7.1 7.5 ``` @@ -383,11 +383,11 @@ We can use `==` to mimic the previous method of indexing by name (remember you have to use `==` rather than `=` for comparisons): -```r +``` r x[names(x) == "a"] ``` -```{.output} +``` output a 5.4 ``` @@ -432,13 +432,13 @@ vector are `TRUE`). Given the following code: -```r +``` r x <- c(5.4, 6.2, 7.1, 4.8, 7.5) names(x) <- c('a', 'b', 'c', 'd', 'e') print(x) ``` -```{.output} +``` output a b c d e 5.4 6.2 7.1 4.8 7.5 ``` @@ -450,12 +450,12 @@ Write a subsetting command to return the values in x that are greater than 4 and ## Solution to challenge 2 -```r +``` r x_subset <- x[x<7 & x>4] print(x_subset) ``` -```{.output} +``` output a b d 5.4 6.2 4.8 ``` @@ -510,11 +510,11 @@ apply. However they are also two dimensional objects: element corresponds to a column. The resulting object will be a data frame: -```r +``` r head(gapminder[3]) ``` -```{.output} +``` output pop 1 8425333 2 9240934 @@ -527,33 +527,33 @@ head(gapminder[3]) Similarly, `[[` will act to extract *a single column*: -```r +``` r head(gapminder[["lifeExp"]]) ``` -```{.output} +``` output [1] 28.801 30.332 31.997 34.020 36.088 38.438 ``` And `$` provides a convenient shorthand to extract columns by name: -```r +``` r head(gapminder$year) ``` -```{.output} +``` output [1] 1952 1957 1962 1967 1972 1977 ``` To select specific rows and/or columns, you can provide two arguments to `[` -```r +``` r gapminder[1:3, ] ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap 1 Afghanistan 1952 8425333 Asia 28.801 779.4453 2 Afghanistan 1957 9240934 Asia 30.332 820.8530 @@ -564,11 +564,11 @@ If we subset a single row, the result will be a data frame (because the elements are mixed types): -```r +``` r gapminder[3, ] ``` -```{.output} +``` output country year pop continent lifeExp gdpPercap 3 Afghanistan 1962 10267083 Asia 31.997 853.1007 ``` @@ -585,21 +585,21 @@ Fix each of the following common data frame subsetting errors: 1. Extract observations collected for the year 1957 - ```r + ``` r gapminder[gapminder$year = 1957, ] ``` 2. Extract all columns except 1 through to 4 - ```r + ``` r gapminder[, -1:4] ``` 3. Extract the rows where the life expectancy is longer the 80 years - ```r + ``` r gapminder[gapminder$lifeExp > 80] ``` @@ -607,7 +607,7 @@ Fix each of the following common data frame subsetting errors: (`lifeExp` and `gdpPercap`). - ```r + ``` r gapminder[1, 4, 5] ``` @@ -615,7 +615,7 @@ Fix each of the following common data frame subsetting errors: and 2007 - ```r + ``` r gapminder[gapminder$year == 2002 | 2007,] ``` @@ -628,7 +628,7 @@ Fix each of the following common data frame subsetting errors: 1. Extract observations collected for the year 1957 - ```r + ``` r # gapminder[gapminder$year = 1957, ] gapminder[gapminder$year == 1957, ] ``` @@ -636,7 +636,7 @@ Fix each of the following common data frame subsetting errors: 2. Extract all columns except 1 through to 4 - ```r + ``` r # gapminder[, -1:4] gapminder[,-c(1:4)] ``` @@ -644,7 +644,7 @@ Fix each of the following common data frame subsetting errors: 3. Extract the rows where the life expectancy is longer the 80 years - ```r + ``` r # gapminder[gapminder$lifeExp > 80] gapminder[gapminder$lifeExp > 80,] ``` @@ -653,7 +653,7 @@ Fix each of the following common data frame subsetting errors: (`lifeExp` and `gdpPercap`). - ```r + ``` r # gapminder[1, 4, 5] gapminder[1, c(4, 5)] ``` @@ -662,7 +662,7 @@ Fix each of the following common data frame subsetting errors: and 2007 - ```r + ``` r # gapminder[gapminder$year == 2002 | 2007,] gapminder[gapminder$year == 2002 | gapminder$year == 2007,] gapminder[gapminder$year %in% c(2002, 2007),] @@ -690,7 +690,7 @@ Fix each of the following common data frame subsetting errors: 2. -```r +``` r gapminder_small <- gapminder[c(1:9, 19:23),] ``` diff --git a/06-dplyr.md b/06-dplyr.md index b208d9e93..29923a929 100644 --- a/06-dplyr.md +++ b/06-dplyr.md @@ -27,27 +27,27 @@ data by a certain variable(s), or we even calculate summary statistics. We can do these operations using the normal base R operations: -```r +``` r mean(gapminder[gapminder$continent == "Africa", "gdpPercap"]) ``` -```{.output} +``` output [1] 2193.755 ``` -```r +``` r mean(gapminder[gapminder$continent == "Americas", "gdpPercap"]) ``` -```{.output} +``` output [1] 7136.11 ``` -```r +``` r mean(gapminder[gapminder$continent == "Asia", "gdpPercap"]) ``` -```{.output} +``` output [1] 7902.15 ``` @@ -85,14 +85,14 @@ pipes (`%>%`) to combine them. If you have have not installed this package earlier, please do so: -```r +``` r install.packages('dplyr') ``` Now let's load the package: -```r +``` r library("dplyr") ``` @@ -103,7 +103,7 @@ our dataframe we could use the `select()` function. This will keep only the variables you select. -```r +``` r year_country_gdp <- select(gapminder, year, country, gdpPercap) ``` @@ -116,7 +116,7 @@ is unlike anything we've seen in R before, let's repeat what we've done above using pipes. -```r +``` r year_country_gdp <- gapminder %>% select(year,country,gdpPercap) ``` @@ -134,7 +134,7 @@ If we now wanted to move forward with the above, but only with European countries, we can combine `select` and `filter` -```r +``` r year_country_gdp_euro <- gapminder %>% filter(continent == "Europe") %>% select(year, country, gdpPercap) @@ -154,7 +154,7 @@ have and why? ## Solution to Challenge 1 -```r +``` r year_country_lifeExp_Africa <- gapminder %>% filter(continent=="Africa") %>% select(year,country,lifeExp) @@ -180,11 +180,11 @@ can use `group_by()`, which will essentially use every unique criteria that you could have used in filter. -```r +``` r str(gapminder) ``` -```{.output} +``` output 'data.frame': 1704 obs. of 6 variables: $ country : chr "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... $ year : int 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... @@ -194,11 +194,11 @@ str(gapminder) $ gdpPercap: num 779 821 853 836 740 ... ``` -```r +``` r gapminder %>% group_by(continent) %>% str() ``` -```{.output} +``` output gropd_df [1,704 × 6] (S3: grouped_df/tbl_df/tbl/data.frame) $ country : chr [1:1704] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ... $ year : int [1:1704] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ... @@ -236,7 +236,7 @@ original dataframe into multiple pieces, then we can run functions (e.g. `mean()` or `sd()`) within `summarize()`. -```r +``` r gdp_bycontinents <- gapminder %>% group_by(continent) %>% summarize(mean_gdpPercap = mean(gdpPercap)) @@ -244,7 +244,7 @@ gdp_bycontinents <- gapminder %>% gdp_bycontinents ``` -```{.output} +``` output # A tibble: 5 × 2 continent mean_gdpPercap @@ -272,7 +272,7 @@ expectancy and which has the shortest average life expectancy? ## Solution to Challenge 2 -```r +``` r lifeExp_bycountry <- gapminder %>% group_by(country) %>% summarize(mean_lifeExp=mean(lifeExp)) @@ -281,7 +281,7 @@ lifeExp_bycountry %>% filter(mean_lifeExp == min(mean_lifeExp) | mean_lifeExp == max(mean_lifeExp)) ``` -```{.output} +``` output # A tibble: 2 × 2 country mean_lifeExp @@ -296,26 +296,26 @@ from the `dplyr` package. You can use `desc()` inside `arrange()` to sort in descending order. -```r +``` r lifeExp_bycountry %>% arrange(mean_lifeExp) %>% head(1) ``` -```{.output} +``` output # A tibble: 1 × 2 country mean_lifeExp 1 Sierra Leone 36.8 ``` -```r +``` r lifeExp_bycountry %>% arrange(desc(mean_lifeExp)) %>% head(1) ``` -```{.output} +``` output # A tibble: 1 × 2 country mean_lifeExp @@ -329,13 +329,13 @@ lifeExp_bycountry %>% The function `group_by()` allows us to group by multiple variables. Let's group by `year` and `continent`. -```r +``` r gdp_bycontinents_byyear <- gapminder %>% group_by(continent, year) %>% summarize(mean_gdpPercap = mean(gdpPercap)) ``` -```{.output} +``` output `summarise()` has grouped output by 'continent'. You can override using the `.groups` argument. ``` @@ -343,7 +343,7 @@ gdp_bycontinents_byyear <- gapminder %>% That is already quite powerful, but it gets even better! You're not limited to defining 1 new variable in `summarize()`. -```r +``` r gdp_pop_bycontinents_byyear <- gapminder %>% group_by(continent,year) %>% summarize(mean_gdpPercap = mean(gdpPercap), @@ -352,7 +352,7 @@ gdp_pop_bycontinents_byyear <- gapminder %>% sd_pop = sd(pop)) ``` -```{.output} +``` output `summarise()` has grouped output by 'continent'. You can override using the `.groups` argument. ``` @@ -368,13 +368,13 @@ of one or more columns that contain the groups we are interested in, and we can optionally sort the results in descending order by adding `sort=TRUE`: -```r +``` r gapminder %>% filter(year == 2002) %>% count(continent, sort = TRUE) ``` -```{.output} +``` output continent n 1 Africa 52 2 Asia 33 @@ -388,13 +388,13 @@ is useful. For instance, if we wanted to get the standard error of the life expectancy per continent: -```r +``` r gapminder %>% group_by(continent) %>% summarize(se_le = sd(lifeExp)/sqrt(n())) ``` -```{.output} +``` output # A tibble: 5 × 2 continent se_le @@ -408,7 +408,7 @@ gapminder %>% You can also chain together several summary operations; in this case calculating the `minimum`, `maximum`, `mean` and `se` of each continent's per-country life-expectancy: -```r +``` r gapminder %>% group_by(continent) %>% summarize( @@ -418,7 +418,7 @@ gapminder %>% se_le = sd(lifeExp)/sqrt(n())) ``` -```{.output} +``` output # A tibble: 5 × 5 continent mean_le min_le max_le se_le @@ -434,7 +434,7 @@ gapminder %>% We can also create new variables prior to (or even after) summarizing information using `mutate()`. -```r +``` r gdp_pop_bycontinents_byyear <- gapminder %>% mutate(gdp_billion = gdpPercap*pop/10^9) %>% group_by(continent, year) %>% @@ -446,7 +446,7 @@ gdp_pop_bycontinents_byyear <- gapminder %>% sd_gdp_billion = sd(gdp_billion)) ``` -```{.output} +``` output `summarise()` has grouped output by 'continent'. You can override using the `.groups` argument. ``` diff --git a/07-plot-ggplot2.md b/07-plot-ggplot2.md index 6973ccec6..58868fb12 100644 --- a/07-plot-ggplot2.md +++ b/07-plot-ggplot2.md @@ -69,7 +69,7 @@ want to plot the "lifeExp" column of the gapminder data frame on the x-axis. We for histograms. -```r +``` r library("ggplot2") ggplot(data = gapminder, aes(x = lifeExp)) + geom_histogram() @@ -83,7 +83,7 @@ ggplot(data = gapminder, aes(x = lifeExp)) + By itself, the call to `ggplot` isn't enough to draw a figure: -```r +``` r ggplot(data = gapminder, aes(x = lifeExp)) ``` @@ -95,12 +95,12 @@ tells `ggplot` we want to visually represent the distribution of one variable (in our case "lifeExp"): -```r +``` r ggplot(data = gapminder, aes(x = lifeExp)) + geom_histogram() ``` -```{.output} +``` output `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` @@ -122,12 +122,12 @@ expectancy: ## Solution to challenge 1 -```r +``` r ggplot(data = gapminder, aes(x = gdpPercap)) + geom_histogram() ``` -```{.output} +``` output `stat_bin()` using `bins = 30`. Pick better value with `binwidth`. ``` @@ -146,7 +146,7 @@ recent year and only from countries in the Americas. -```r +``` r gapminder_small <- filter(gapminder, year == 2007, continent == "Americas") ``` @@ -155,7 +155,7 @@ We will plot countries on the x-axis (listed in alphabetic order by default) and gdp per capita on the y-axis. -```r +``` r ggplot(data = gapminder_small, aes(x = country, y = gdpPercap)) + geom_col() ``` @@ -170,7 +170,7 @@ x-axis labels. A quick fix to this is the add the `coord_flip()` function to the end of our plot code. -```r +``` r ggplot(data = gapminder_small, aes(x = country, y = gdpPercap)) + geom_col() + coord_flip() @@ -206,7 +206,7 @@ First we create a new object with our filtered data: -```r +``` r gapminder_small_2 <- gapminder %>% filter(continent == "Americas", year %in% c(1952, 2007)) @@ -222,7 +222,7 @@ The default behavior for `postion` in `geom_col()` is "stack". -```r +``` r ggplot(gapminder_small_2, aes(x = country, y = gdpPercap, fill = as.factor(year))) + diff --git a/08-writing-data.md b/08-writing-data.md index b6d3f295e..cb1e1e82c 100644 --- a/08-writing-data.md +++ b/08-writing-data.md @@ -42,7 +42,7 @@ latest plot by default. You can control the size and resolution using the arguments to this function. -```r +``` r ggplot(data = gapminder, aes(x = gdpPercap)) + geom_histogram() ggsave("Distribution-of-gdpPercap.pdf", width=12, height=4) @@ -65,7 +65,7 @@ previous episode. ## Solution to challenge 1 -```r +``` r ggplot(data = gapminder_small_2, aes(x = country, y = gdpPercap, fill = as.factor(year))) + geom_col(position = "dodge") + @@ -94,7 +94,7 @@ Let's create a data-cleaning script, for this analysis, we only want to focus on the gapminder data for Australia: -```r +``` r aust_subset <- filter(gapminder, country == "Australia") write.csv(aust_subset, @@ -115,7 +115,7 @@ Let's look at the help file to work out how to change this behaviour. -```r +``` r ?write.csv ``` @@ -124,7 +124,7 @@ column names when writing data to a file. To over write this behavior, we can do the following: -```r +``` r write.csv( aust_subset, file="cleaned-data/gapminder-aus.csv", @@ -145,7 +145,7 @@ in the `cleaned-data/` directory. ## Solution to challenge 2 -```r +``` r gapminder_after_1990 <- filter(gapminder, year > 1990) write.csv(gapminder_after_1990, diff --git a/config.yaml b/config.yaml deleted file mode 100644 index faedf54ba..000000000 --- a/config.yaml +++ /dev/null @@ -1,88 +0,0 @@ -#------------------------------------------------------------ -# Values for this lesson. -#------------------------------------------------------------ - -# Which carpentry is this (swc, dc, lc, or cp)? -# swc: Software Carpentry -# dc: Data Carpentry -# lc: Library Carpentry -# cp: Carpentries (to use for instructor training for instance) -# incubator: The Carpentries Incubator -carpentry: 'dc' - -# Overall title for pages. -title: 'Introduction to R for Geospatial Data' - -# Date the lesson was created (YYYY-MM-DD, this is empty by default) -created: '2018-04-05' - -# Comma-separated list of keywords for the lesson -keywords: 'software, data, lesson, The Carpentries' - -# Life cycle stage of the lesson -# possible values: pre-alpha, alpha, beta, stable -life_cycle: 'stable' - -# License of the lesson materials (recommended CC-BY 4.0) -license: 'CC-BY 4.0' - -# Link to the source repository for this lesson -source: 'https://github.com/datacarpentry/r-intro-geospatial' - -# Default branch of your lesson -branch: 'main' - -# Who to contact if there are any issues -contact: 'team@carpentries.org' - -# Navigation ------------------------------------------------ -# -# Use the following menu items to specify the order of -# individual pages in each dropdown section. Leave blank to -# include all pages in the folder. -# -# Example ------------- -# -# episodes: -# - introduction.md -# - first-steps.md -# -# learners: -# - setup.md -# -# instructors: -# - instructor-notes.md -# -# profiles: -# - one-learner.md -# - another-learner.md - -# Order of episodes in your lesson -episodes: -- 01-rstudio-intro.Rmd -- 02-project-intro.Rmd -- 03-data-structures-part1.Rmd -- 04-data-structures-part2.Rmd -- 05-data-subsetting.Rmd -- 06-dplyr.Rmd -- 07-plot-ggplot2.Rmd -- 08-writing-data.Rmd - -# Information for Learners -learners: - -# Information for Instructors -instructors: - -# Learner Profiles -profiles: - -# Customisation --------------------------------------------- -# -# This space below is where custom yaml items (e.g. pinning -# sandpaper and varnish versions) should live - - -url: 'https://datacarpentry.github.io/r-intro-geospatial' -analytics: carpentries -lang: en diff --git a/fig/07-plot-ggplot2-rendered-gpd-per-cap-1.png b/fig/07-plot-ggplot2-rendered-gpd-per-cap-1.png index a33d3e0f5042a8bdb098a07fcb3ea39690c75c8f..d361d101ac820d82a2fc94aa7567fd60f4abf5df 100644 GIT binary patch delta 7999 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 delta 8048 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