Basic Functionality of R and Variables

Q1. Data Types

a)

R in its most basic form can be used as a calculator. Write some coded math expressions using at least three different operators (including at least one trigonometric function).

Note: R follows the standard order of operations, but this can be controlled by wrapping any expression in ().

2/1
## [1] 2
5+2
## [1] 7
3*6
## [1] 18

b)

Name and give an example of the five base data types in R:

# Character
'some text'
## [1] "some text"
# Numeric
123.456
## [1] 123.456
# Integer
1234L
## [1] 1234
# Logical
TRUE
## [1] TRUE
# Complex
2 + 3i
## [1] 2+3i

c)

Construct a vector in R.

A vector is a data structure in R that contains multiple entries of the same type.

c('hello','mgt','205')
## [1] "hello" "mgt"   "205"

Q2. Variables

Variables are a reference to data in R and can be assigned any valid data structure. Variables can be used anywhere the data that they are referencing could be and serve as the building blocks for working with data in R as they can be composed.

a)

Create numeric variables x and y independently, then add x and y to a new variable z.

x <- 1
y <- 5
z <- x+y
z
## [1] 6

Q3. Functions

  • Built in functions R’s built in functions known as ‘base R’ form an incredibly powerful statistical package that can be used in a range of ways to extract information from data. Here we cover the basic usage of very common R functions.

a)

i)

Create a sequence from 1 up to 10

seq(1,10)
##  [1]  1  2  3  4  5  6  7  8  9 10

ii)

What is the sum of all numbers from 1 to 12345?

sum(1:12345)
## [1] 76205685

b)

Generate 100 normally distributed random numbers

rnorm(100)
##   [1] -0.65224431  0.87336354 -0.44478956  0.09473785  1.66327074 -0.19818772
##   [7] -0.06343406  2.07922912 -1.43971151 -0.58233781  0.30364482 -0.25991212
##  [13] -1.40943918  1.44158904 -1.11211398  0.43631277 -1.97947965  0.06522568
##  [19]  0.68572148  0.41469544 -1.36974787  0.17791996 -0.92541013 -0.20791480
##  [25]  1.61092007 -0.80778988  0.64393640  0.21582675 -0.08770471  0.95976846
##  [31]  1.36964449 -0.01499405  0.31108762 -0.51014082  0.41897948 -1.21889678
##  [37]  1.21444577  0.47300343  0.48271608 -0.71129573 -0.34325141 -0.71205241
##  [43]  0.57164957  0.02461987  0.54944498  1.21676609  1.74449911  1.29208632
##  [49]  0.49562534 -2.41387089  0.55069610  0.56095039 -0.39379522  0.31246153
##  [55]  0.68647504 -0.50526197 -0.37595198  0.90562184 -0.29458042 -0.23191775
##  [61]  0.57708825 -0.52144469 -1.18089878 -0.50878077 -2.01931453  0.61627056
##  [67]  1.53238947 -0.86390031 -0.03893740  0.30245890 -0.86574283  0.75351592
##  [73] -0.61451069  1.06221098 -1.34382913 -0.64263340  0.85241019  0.66697617
##  [79]  0.84743735 -1.90630038 -0.86837040  0.33791038  0.03789259  0.60081069
##  [85] -1.07155374  0.65919866 -0.30203517 -0.57466896 -0.61297224 -2.39338128
##  [91] -2.52398321 -0.99869268 -1.34138454 -0.72269478  0.51216375  0.49134665
##  [97] -0.93111068 -1.49223106  2.51043792  1.23359239

c)

i)

Sample 30 random whole numbers between 1 and 500

sample(seq(1,500),30)
##  [1] 323  68 313  71 446 162 104 346  29 121 187 160  35 448 403 285 432  36 496
## [20] 154 379 353 144 354 299 284  94 252 457 191

ii)

Choose and show 10 randomly generated normally distributed numbers

sample(rnorm(10))
##  [1]  0.74453564  0.50800541 -0.07706164  0.35395147  0.87349352  2.49463153
##  [7]  0.97321708 -0.35854366 -0.87946702 -0.04663564

d)

Simulate flipping a coin 100 times with with 1s and 0s standing for heads and tails respectively. Count the number of heads.

sum(sample(c(0,1),size=100,replace=TRUE))
## [1] 50

R Packages and functions

‘R packages’ are collections of useful functions created by academics and industry professionals that have been published openly for use by anyone. One of the most widely used collection of packages is the tidyverse, which provides a consistent way of working with data from the beginning of an analysis to the end.

User defined functions

Functions can be defined as needed to simplify operations or reduce repetition in code. The function() keyword is used to do this. ‘Arguments’ are passed to functions when they are called with parentheses and are separated by commas. These arguments can be accessed inside the function.

e)

Define a function called add_one that adds 1 to its input.

add_one <- function(num){
 num + 1
}

f)

Define a function that takes 2 arguments and randomly returns one.

pick_one <- function(one, two){
 vec <- c(one, two)
 sample(vec, size = 1)
}

Reading Data and Working with Data Frames

From here on out we will be using the tidyverse. The tidyverse provides a consistent way to work with data, and extends the functionality of base R. In particular, we will be using dplyr for data processing, along with ggplot2 for visualization and readr for data reading.

Q1. Reading Data

Run the code block below.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

a)

Load in the starwars data.

starwars = read_csv("starwars.csv")
## Rows: 87 Columns: 11
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (8): name, hair_color, skin_color, eye_color, sex, gender, homeworld, sp...
## dbl (3): height, mass, birth_year
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

b)

List the first 6 rows of starwars.

head(starwars)
## # A tibble: 6 × 11
##   name      height  mass hair_color skin_color eye_color birth_year sex   gender
##   <chr>      <dbl> <dbl> <chr>      <chr>      <chr>          <dbl> <chr> <chr> 
## 1 Luke Sky…    172    77 blond      fair       blue            19   male  mascu…
## 2 C-3PO        167    75 <NA>       gold       yellow         112   none  mascu…
## 3 R2-D2         96    32 <NA>       white, bl… red             33   none  mascu…
## 4 Darth Va…    202   136 none       white      yellow          41.9 male  mascu…
## 5 Leia Org…    150    49 brown      light      brown           19   fema… femin…
## 6 Owen Lars    178   120 brown, gr… light      blue            52   male  mascu…
## # ℹ 2 more variables: homeworld <chr>, species <chr>

c)

Get the number of rows and number of columns in starwars.

nrow(starwars)
## [1] 87
ncol(starwars)
## [1] 11
dim(starwars)
## [1] 87 11

Q2. Data Pipelines ( %>% )

Often multiple processing steps are required for data frames, but the intermediate results are often not that important. There are a number of ways to apply functions in succession, but the preferred standard is to use the forward pipe operator %>%. This operator takes whatever expression is on its left hand side and uses this expression as the first argument of the function on its right hand side. i.e.  x %>% f %>% g %>% h is equivalent to h(g(f(x)))

https://r4ds.had.co.nz/pipes.html https://magrittr.tidyverse.org

a)

Take the head of starwars and find how many rows are in it.

starwars %>% 
 head() %>%
 nrow()
## [1] 6

Q3. Working with Data Frames

a)

i)

How many males are in the data set?

starwars %>%
  filter(sex == 'male') %>%
  nrow()
## [1] 60

ii)

How many humans with blue eyes are in the data set?

starwars %>%
  filter(species == 'Human', eye_color == 'blue') %>%
  nrow()
## [1] 12

b)

List the tallest 3 humans, showing only name and height columns.

starwars %>%
  filter(species == 'Human') %>%
  arrange(desc(height)) %>%
  head(3) %>%
  select(name, height)
## # A tibble: 3 × 2
##   name         height
##   <chr>         <dbl>
## 1 Darth Vader     202
## 2 Qui-Gon Jinn    193
## 3 Dooku           193

c)

Show the mean height and mass of humans.

i)

starwars %>%
  filter(species == 'Human') %>%
  summarise(
    mean_height = mean(height, na.rm = TRUE),
    mean_mass = mean(mass, na.rm = TRUE)
  )
## # A tibble: 1 × 2
##   mean_height mean_mass
##         <dbl>     <dbl>
## 1        177.      82.8

ii)

Show the mean height and mass of humans grouped by sex.

starwars %>%
  filter(species == 'Human') %>%
  group_by(sex) %>%
  summarise(
    mean_height = mean(height, na.rm = TRUE),
    mean_mass = mean(mass, na.rm = TRUE)
  )
## # A tibble: 2 × 3
##   sex    mean_height mean_mass
##   <chr>        <dbl>     <dbl>
## 1 female        160.      56.3
## 2 male          182.      87.0

d)

Get the 2 shortest masculine and feminine characters, displaying only name, height and gender columns (you must remove missing values for gender).

starwars %>%
  filter(gender == 'masculine') %>%
  arrange(height) %>%
  head(2) %>%
  select(name, height, gender)
## # A tibble: 2 × 3
##   name          height gender   
##   <chr>          <dbl> <chr>    
## 1 Yoda              66 masculine
## 2 Ratts Tyerell     79 masculine
starwars %>%
  filter(gender == 'feminine') %>%
  arrange(height) %>%
  head(2) %>%
  select(name, height, gender)
## # A tibble: 2 × 3
##   name        height gender  
##   <chr>        <dbl> <chr>   
## 1 R4-P17          96 feminine
## 2 Leia Organa    150 feminine

Data Visualization

Base R has its own plotting utilities, but they are rarely for creating presentable visualizations as they are difficult to configure and do not have consistent behavior for different plot types. We will be using the ggplot2 package, which is the industry standard for data visualization as it uses a consistent ‘grammar’ to construct all types of visualizations, produces high quality outputs by default and is easy to configure.

We will also be using the palmerpenguins educational data package for the data underlying our plots.

Run the code block below.

#install.packages("palmerpenguins")
library(palmerpenguins)

Q1)

a)

Create a scatter plot with bill depth on the x axis and body mass on the y axis.

penguins %>% 
 ggplot(aes(x = bill_depth_mm, y = body_mass_g)) + 
 geom_point()
## Warning: Removed 2 rows containing missing values (`geom_point()`).

b)

Color this scatter plot by species.

penguins %>% 
 ggplot(aes(x = bill_depth_mm, y = body_mass_g, color = species)) + 
 geom_point()
## Warning: Removed 2 rows containing missing values (`geom_point()`).

c)

Add an appropriate human-readable title, along with axis and legend labels.

penguins %>% 
 ggplot(aes(x = bill_depth_mm, y = body_mass_g, color = species)) + 
 geom_point() + 
 ggtitle("Body Mass vs Bill Depth for Penguin Species") + 
 labs(x = "Bill Depth (mm)", y = "Body Mass (g)", color = 'Penguin Species')
## Warning: Removed 2 rows containing missing values (`geom_point()`).

Q2

Construct a filled bar chart of species, filled by island.

penguins %>% 
 ggplot(aes(x = species, fill = island)) + 
 geom_bar()

Q3

a)

Construct a histogram of flipper length.

penguins %>% 
 ggplot(aes(x = flipper_length_mm)) + 
 geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing non-finite values (`stat_bin()`).

b)

Facet this histogram by species

penguins %>% 
 ggplot(aes(x = flipper_length_mm)) + 
 geom_histogram() + 
 facet_wrap(~species)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 2 rows containing non-finite values (`stat_bin()`).

c)

Compare the flipper length distributions between different species using density geom with an alpha.

penguins %>% 
 ggplot(aes(x = flipper_length_mm, fill = species)) + 
 geom_density(alpha = 0.2)
## Warning: Removed 2 rows containing non-finite values (`stat_density()`).