RStudio Reference Guide for MATH 135

1 Getting Started with RStudio and Quarto

This is a guide to help you get started with using RStudio. We will be using RStudio in this class to model and visualize functions in order to work with data and apply concepts from calculus. The programming language used in RStudio is called R and is used by professional statisticians and mathematicians.

In this course, we use Quarto Markdown files, which have the extension .qmd. A Quarto document combines R code, mathematical notation (\(\LaTeX\)), and written text (Markdown) all in one file.


1.1 First Log-in

If you have no experience with RStudio, I highly recommend only using the Macalester RStudio server, located at https://rstudio.macalester.edu/. You will sign in with your Macalester username and password.

If you see this page, you can click “New Session”. New Session Page

Once you open the RStudio window, you will see something like this: RStudio Window There are a few main areas of the RStudio window:

  1. In the top left, you will find the edit toolbar and the tabs for your open files. You will work primarily in the source file. You want to make sure your file type is Quarto. You can switch file types on the bottom right of the Source panel. The output of your code will show up under each code block.

    In the bottom left, we have the console and command line. It is a great place to test code and serves as a basic calculator. Code you write here will not be saved. The output of your code and any error messages will also show up here.

  2. If something is not working, try saving your files, then quitting and restarting by clicking Quit Session (orange power button at the top right).

  3. This panel keeps track of your work. The environment tab shows all the variables you have named in the session (including data, functions, and lists) and gives you a preview of them. The history tab tracks the pieces of code you run.

  4. The Files tab shows you all the folders and files you have saved. This is where you will go to upload and export files. You will want to organize your files to be able to access them easily later. The Packages tab shows you which packages are available and loaded into RStudio. The Help tab explains how functions work and what type of parameters you need to give them.


1.2 Working with a Quarto File

In this class, we’ll be working with code a lot: writing it, running it, analyzing it, and commenting on it. We’ll also be going back to code we’ve already used and tweaking it to solve new but related questions. For all of these reasons, we’re going to use RMarkdown notebooks.

The notebook will run large blocks of code at a time and show the output right next to the code. You can also add comments to your code to make a note of what it does so that you can look back on it later.

You can render your file by clicking on the Render button near the top left of the RStudio window, near your file tabs.

1.2.1 Open or Upload a New File

To open a new document, you can go to File > New File > Quarto Document or click the New File icon (paper with a green plus sign) under Files.

To upload an activity file, you will first download to activity .qmd file from Moodle. Then, in the bottom right panel, go to Files > Upload to upload the file. Click ‘Choose File’ and select the file you would like to upload. Make sure to move the file into an appropriate folder by checking the box next to the file name and clicking the gear icon, then Move.

1.2.2 Starting Your File

At the beginning of a new document, include the document information and settings provided in the activity instructions. You generally do not need to change these settings included in an activity file. You should, however, replace "Your Name" with your name and give your file a reasonable title and file name.

The very start of your file should look something like this:

---
title: "Title"
author: "Your Name"
format:
  html:
    toc: true
    toc-depth: 3
    theme: cosmo
    self-contained: true
    code-tools: true
    number-sections: true
---

1.2.3 Loading Packages

Include this code chunk near the beginning of your document. The setup chunk loads the packages needed for the activities.

knitr::opts_chunk$set(echo = TRUE)
library("mosaic")
Registered S3 method overwritten by 'mosaic':
  method                           from   
  fortify.SpatialPolygonsDataFrame ggplot2

The 'mosaic' package masks several functions from core packages in order to add 
additional features.  The original behavior of these functions should not be affected by this.

Attaching package: 'mosaic'
The following objects are masked from 'package:dplyr':

    count, do, tally
The following object is masked from 'package:Matrix':

    mean
The following object is masked from 'package:ggplot2':

    stat
The following objects are masked from 'package:stats':

    binom.test, cor, cor.test, cov, fivenum, IQR, median, prop.test,
    quantile, sd, t.test, var
The following objects are masked from 'package:base':

    max, mean, min, prod, range, sample, sum
library("mosaicCalc")

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

    D

You only need one setup chunk. The packages must be loaded before you use their functions.

1.2.4 Using Markdown to Format Text

The regular text uses Markdown, which has simple commands to create formatting such has sections, bold, italic, links, itemized lists, and much more.

Paragraphs: You can type regularly to write a paragraph. Skipping a line starts a new paragraph. But if you do not skip a line then it is part of the same paragraph

Headings: Use one hashtag # in front of your text to get a heading. Use two hashtags ## in front of your text to get a subheading. You can keep adding hashtags to get further subheadings.

Bold and Italics: You get italics by surrounding your text with asterisks, like * text *. You get bold text by surrounding your text with double asterisks, like this: ** text ** If you use three asterisks, you will get italicized and bolded text.

1.2.5 Using R to Run Code

Your R code must be inside a code block to run properly. When you render your .qmd file, the code blocks will be executed in the order they’re written. You can run an individual block without rendering the entire file by clicking on the green arrow in the upper right corner of that code block.

To add a code block to your file, you can do one of two things:

  1. Click on the green +C at the top of the Source panel. Choose the R option.

  2. Type the following into the source file:

    ```{r}
    (code goes here)
    ```

1.3 Saving and Formatting Your Activity

Before submitting your activity, make sure your file is saved and formatted correctly.

  1. Change your name at the top of the activity. Replace "Your Name" with your actual name wherever it appears at the beginning of the document.

  2. Give your files meaningful names. For example, use RActivity1-YourName.qmd for your Quarto file.

  3. Save all of your Quarto files in a dedicated folder for this class. Keep your .qmd file in a course folder so you can find it and continue working on it later.

  4. Check your work before submitting. Make sure you have answered all questions, included your R code, and written explanations wherever requested.

1.4 Submitting Your Activity to Moodle

You will submit the .html file, not the .qmd file, to Moodle. The ` file is the finished version of your activity, including your written answers, code, and plots.

Follow these steps in RStudio.

  1. Save your work. Click the Save icon or select File > Save.

  2. Render your document. Click the Render button near the top of the RStudio editor pane, where you write your Quarto document. Wait for the rendering process to finish. If errors appear, fix them before continuing.

  3. Open the Files pane. In the lower-right pane of RStudio, click the Files tab and navigate to the folder where you stored your .qmd file. After rendering, The .html file is saved in the same folder as your .qmd file.

  4. Download the file. Check the box to the left of your .html file. Then, click the gear icon and More > Export. Download the file to your computer.

  5. Check your .html file before submitting. Open it and make sure your name, written answers, code, and plots appear correctly. Check that all questions are answered.

  6. Once you have rendered and downloaded your .html file, submit it on Moodle. Make sure that the file name follows to appropriate format.


2 Troubleshooting

Common errors and what they usually mean:

  • Nothing ran, and the console shows +: You may have an unclosed parenthesis, bracket, or quotation mark. Complete the expression or press Escape to cancel it.
  • Unexpected symbol: You may have forgotten a multiplication sign (*) or included an invalid character.
  • Object not found: Check that you created the object first and spelled its name correctly. R is case-sensitive.
  • Could not find function: Check that the package containing the function is loaded.
  • Non-numeric argument to mathematical function: Check that your input is numeric and not text or a factor.
  • Missing values (NA): Check the data for missing values and consider whether the function you are using can handle them.
  • Error in fitModel(): Check your formula, variable names, starting values, and whether the model is appropriate for the data.
  • Error in makeFun(): Make sure the variables after ~ match the variables in the expression before it.
  • Quarto rendering fails: Check that your code runs, your packages are installed, and your document is properly formatted.

3 Functions and Expressions

3.1 Basic Calculations

You can run basic calculations in an R block:

8+13
[1] 21
7*9
[1] 63
sin(pi/2)
[1] 1
sqrt(2)
[1] 1.414214
(2.25)^3
[1] 11.39062
8*cos(pi/6)
[1] 6.928203

3.2 Defining Variables

To define a variable, we use the following syntax:

x <- 5

The arrow tells RStudio to give the variable x the value of 5. Then we can ask RStudio what value is stored in x:

x
[1] 5

3.3 Vectors (Lists) and Sequences

Use c() to combine values into a vector (aka a list) and seq() to create a sequence.

primes <- c(2, 3, 5, 7, 11, 13, 17, 19, 23, 29) 
primes 
 [1]  2  3  5  7 11 13 17 19 23 29
some_data <- c(5, -2, 7, 3, -10, 15) 
some_data  
[1]   5  -2   7   3 -10  15
seq(1, 10) 
 [1]  1  2  3  4  5  6  7  8  9 10
seq(5, 12, by = 0.5)
 [1]  5.0  5.5  6.0  6.5  7.0  7.5  8.0  8.5  9.0  9.5 10.0 10.5 11.0 11.5 12.0
  • c() combines values into an ordered list.
  • seq(from, to, by) generates a sequence where by specifies the step size.

3.4 Defining and Evaluating a Function with makeFun()

Use makeFun() from the mosaic package to create an R function from a mathematical expression.

The general syntax is:

f <- makeFun(EXPRESSION ~ INPUT)

Examples:

f <- makeFun(x^2 + 5*x + 6 ~ x)
g <- makeFun(sin(x)^2 - 1/2 ~ x)
P <- makeFun(5 * exp(0.25*t) ~ t)
Q <- makeFun(12.38 * (1.041)^t ~ t)

Notes: - Always use * for multiplication. - The variable on both sides of ~ must match (e.g., x^2 ~ x, not x^2 ~ t).

You can evaluate functions at specific input values:

f(-10)
[1] 56
g(0)
[1] -0.5
P(6)
[1] 22.40845
Q(-1/2)
[1] 12.13376

Reminders:

  • Use * for multiplication: 3*x, not 3x.
  • Use ^ for exponents: x^2.
  • The variables in the expression must match the inputs after ~.
  • R distinguishes uppercase and lowercase letters: x and X are different objects.

3.5 Common Mathematical Functions

Mathematical expression R command
\(x^2\) x^2
\(4x^2-7x+3\) 4*x^2 - 7*x + 3
\(\sqrt{x}\) sqrt(x) or x^(1/2)
\(\sqrt[3]{x}\) x^(1/3)
\(\sin(x)\) sin(x)
\(\cos(x)\) cos(x)
\(e^x\) exp(x)
\(\ln(x)\) log(x)
\(\log_{10}(x)\) log10(x)
\(\log_b(x)\) log(x, base = b)
\(|x|\) abs(x)

R uses radians for trigonometric functions.


4 Single-Variable Functions

4.1 Plotting a Function with plotFun()

Use plotFun() to plot a function of one variable. You can specify the horizontal range using xlim. You can also change the color with col and the line width with lwd.

plotFun(
  sin(x) ~ x,
  xlim = c(0, 2*pi),
  col = "red",
  lwd = 2
)

4.2 Plotting with slice_plot() and domain()

Use slice_plot() to plot a mathematical expression over a specified domain.

slice_plot(
  sin(x) ~ x,
  domain(x = 0:2*pi)
)

The domain() function specifies the range of the input variable.

You can customize the plot with labels and colors:

slice_plot(
  sin(x) ~ x,
  domain(x = 0:2*pi),
  color = "blue"
) +
  xlab("x values") +
  ylab("sin(x)") +
  labs(title = "The sine function")

For functions of one variable, plotFun() and slice_plot() are both useful.

5 Functions of Two Variables

A function of two variables has the form

\[ z=f(x,y). \]

The first input is the value of \(x\), and the second is the value of \(y\).

We can use makeFun() to define the function and then visualize it with surface plots, contour plots, and cross-sections.

5.1 Defining and Evaluating a Function with makeFun

Consider

\[ f(x,y)=x^2+y^2. \]

Define the function:

f <- makeFun(x^2 + y^2 ~ x & y)

Evaluate it at particular points:

f(0, 0)
[1] 0
f(-1, 5)
[1] 26

5.2 Surface Plots: surface_plot()

A surface plot shows the height \(z=f(x,y)\) above each point in the \(xy\)-plane.

surface_plot(
  f(x,y) ~ x & y,
  domain(x = -10:10, y = -10:10)
)
Loading required namespace: plotly

The domain specifies the ranges of both input variables.

5.3 Contour Plots: contour_plot()

A contour plot represents a function using curves in the \(xy\)-plane. Every point on the same contour curve has the same output value.

contour_plot(
  f(x,y) ~ x & y,
  domain(x = -10:10, y = -10:10),
  skip = 0,
  n_contours = 8
)

Important arguments:

  • domain(): specifies the ranges of x and y.
  • skip = 0: prevents the plotting function from automatically skipping contour levels.
  • n_contours = 8: requests 8 contour levels.

A contour plot is similar to a topographic map: each curve represents a constant height.

5.4 Cross-Sections: Fixing One Variable

A cross-section is created by fixing one variable and allowing the other to vary.

For example, if we fix \(y=4\), then

\[ f(x,4) = x^2 + (4)^2 = x^2 + 16 \]

The resulting function depends only on \(x\). Here is how you can plot it:

slice_plot(
  f(x,4) ~ x,
  domain(x = -10:10)
) +
  ylab("f(x,4)")

We can fix \(x=1\) and allow \(y\) to vary:

\[ f(1,y) = (1)^2+y^2=1+y^2. \] Notice that the function now depends only on \(y\). Here is the cross-section:

slice_plot(
  f(1,y) ~ y,
  domain(y = -10:10)
) +
  ylab("f(1,y)")


6 Working with Data

6.1 Useful Data Functions

Function Purpose
data() Load or list available data sets
head() Display the first rows of a data set
summary() Summarize variables
dataset$var Access the variable var from the data set called dataset
diff() Calculate consecutive differences
log() Calculate natural logarithms
round() Round numerical values
print() Display a message or object
coef() Extract fitted model coefficients

6.2 mosaicData Package Dataset List

Here is a list of some of the built-in data sets, their descriptions, and suggested variables from the mosaicData package:

Dataset Description Suggested Variables
CPS85 Census information from 1985 exper (# years of experience)
wage (US dollars per hour)
educ (# years of education)
Dimes Weight of dimes year (year dime was minted)
mass (weight of dime in grams)
Galton Heights of adult children and their parents father (father’s height in inches)
mother (mother’s height in inches)
height (child’s height in inches)
GoosePermits Hunters offered money for their goose permits bid (amount offered for permit in US dollars)
keep (# hunters who kept permit)
sell (# hunter who sold permit)
KidsFeet Length and width of fourth graders’ feet length (in centimeters)
width (in centimeters)
RailTrail Weather and number of trail walkers in Florence, MA in 2005 hightemp (daily high temperature in degrees Fahrenheit)
lowtemp (daily low temperature in degrees Fahrenheit)
avgtemp (daily average temperature in degrees Fahrenheit)
precip (amount of precipitation in inches)
volume (number of trail users)
SAT SAT data 1994-1995 expend (expenditure per student in thousands of US dollars)
salary (average salary of teachers in thousands of US dollars)
verbal (average verbal SAT score)
math (average math SAT score)
sat (average total SAT score)
SaratogaHouses Data on houses in Saratoga County, NY in 2006 price (US dollars)
livingArea (square feet)
SnowGR Snowfall data in Grand Rapids, MI going back to 1893 SeasonStart (year)
Total (inches of snow for entire season Jul-Jun)
SwimRecords World records for men and women 1905-2004 time (in seconds)
year (year record was set)
Utilities Data on utilities bills temp (average temperature in degrees Fahrenheit)
kwh (electricity usage in kilo-watt hours)
ccf (gas usage in hundreds of cubic feet (CCF))
totalbill (in US dollars)
gasbill (in US dollars)
elecbill (in US dollars)

6.3 Loading a Data Set

Use data() to load a built-in data set. The head command lets you see the first few rows of a data set.

data(Utilities)
head(Utilities)
  month day year temp kwh ccf thermsPerDay billingDays totalbill gasbill
1    12  29 1999   26 892 194          5.5          36    173.65  112.72
2     1  28 2000   18 533 164          5.6          30    139.18   95.88
3     2  26 2000   24 521 228          8.0          29    177.48  134.65
4     3  25 2000   41 554  16          0.6          28     61.27   15.32
5     4  28 2000   45 638  74          2.2          34    100.33   47.33
6     5  30 2000   60 700 129          4.1          32    153.32   89.87
  elecbill             notes
1    68.25                  
2    43.30                  
3    42.83                  
4    45.95 bad meter reading
5    53.00                  
6    63.45                  

Use $ to access a variable in a data frame. We save it to variables called temp and gasbill so that we can reuse the information.

temp <- Utilities$temp
gasbill <- Utilities$gasbill

Here, temp represents outside temperature and gasbill represents the gas bill.

6.4 Summarizing Data

Use summary() to inspect the minimum, maximum, median, mean, and quartiles of a variable.

summary(temp)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   9.00   30.00   51.00   48.66   69.00   78.00 
summary(gasbill)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   3.42   23.42   55.74   81.24  124.18  240.90 

Summary statistics can help you identify reasonable starting values when fitting a model.

6.5 Plotting Data Points with plotPoints()

Use plotPoints() to create a scatterplot from a data frame. A data frame is a table of data, with rows and columns for x-values and y-values.

In this example, we are using gasbill as the input (x-values) and temp as the output (y-values).

plotPoints(temp ~ gasbill, data = Utilities)

The formula temp ~ gasbill means that temp is plotted on the vertical axis and gasbill on the horizontal axis.

You can also create two vectors to use as your lists of x-values and y-values. They must have the same length.

x_data <- c(2, 3, 5, 8, 13, -4, 10)
y_data <- c(2, 4, 8, 4, 2, 5, 6)

plotPoints(y_data ~ x_data)

A scatterplot helps you identify the general pattern in the data before choosing a model.


6.6 Fitting Models to Data

Use fitModel() from mosaic to estimate the parameters of a mathematical model.

The general syntax is:

f_model <- fitModel(
  output ~ MODEL_EXPRESSION,
  data = DataSet
)

coef(f_model)
  • output is the output variable.
  • MODEL_EXPRESSION describes the general function with parameters in terms of the input variable.
  • data identifies the data frame you are using (the table of data points).
  • The line coef(f_model) displays the parameter values estimated by R.

Here’s an example that fits an exponential function using the fact that \(y = Ce^{kx}\) is equivalent to a linear function \(\ln(y) = \ln(C) + kx\) in terms of the inputs and the log of the outputs.

f_exp <- fitModel(
  log(gasbill) ~ log(C) + k*temp,
  data = Utilities
)

coef(f_exp)
           C            k 
416.49834472  -0.04143475 

6.7 Combining Data and Functions

When fitting a model, it is useful to show the original data and the fitted function on the same plot.

The process is:

  1. Plot the observed data with plotPoints().
  2. Add the fitted function with plotFun(add = TRUE).

For example:

plotPoints(gasbill ~ temp, data = Utilities)

plotFun(
  f_exp(temp) ~ temp,
  add = TRUE,
  col = "red",
  lwd = 2
)

Use the plot to assess whether the model captures the overall pattern of the data.

7 Differentiation

7.1 Estimating Derivatives and Partial Derivatives

Estimate derivative \(f'(x)\) numerically:

f <- makeFun(x^2 + 10*sin(x) ~ x)
h <- c(1, 0.1, 0.01, 0.001, 1e-4, 1e-5, 1e-6, 1e-7)
AROC <- (f(4 + h) - f(4)) / h
AROC
[1] 6.978782 1.952538 1.511513 1.468349 1.464042 1.463612 1.463569 1.463564

The sequence should stabilize as h gets small.

Estimate partial derivatives by varying one variable at a time:

g <- makeFun(exp(x * sin(y)) ~ x & y)
h <- c(1, 0.1, 0.01, 0.001, 1e-4, 1e-5, 1e-6, 1e-7)

# approximate g_x(2,7)
AROC_x <- (g(2 + h, 7) - g(2,7)) / h
AROC_x
[1] 3.456634 2.526691 2.452648 2.445403 2.444680 2.444608 2.444601 2.444600
# approximate g_y(2,7)
AROC_y <- (g(2, 7 + h) - g(2,7)) / h
AROC_y
[1] 3.512524 5.761618 5.628032 5.612215 5.610611 5.610450 5.610434 5.610433

7.2 Exact Derivatives and Partial Derivatives

There are also functions in R that can find the exact values of derivatives and partial derivatives.

To find an exact derivative at a point, we can use the D(x) function. You can see the formula of the derivative and use it to evaluate the derivative at various values of x.

f <- makeFun(x^2 ~ x)
df_dx <- D(f(x) ~ x)

df_dx
function (x) 
2 * x
df_dx(2)
[1] 4

Here is how you can use the same function D() to find partial derivatives:

g <- makeFun(x^2 + 3*y^3 ~ x & y)

# partial derivative in the x-direction
dg_dx <- D(g(x,y) ~ x)
dg_dx
function (x, y) 
2 * x
dg_dx(2,3)
[1] 4
# partial derivative in the y-direction
dg_dy <- D(g(x,y) ~ y)
dg_dy
function (x = 5, y) 
9 * y^2
dg_dy(2,3)
[1] 81

7.3 Gradient Vector

You can create a gradient vector by putting your partial derivatives in a function and combining them using the cbind() function:

g <- makeFun(x^2 + 3*y^3 ~ x & y)

dg_dx <- D(g(x,y) ~ x)
dg_dy <- D(g(x,y) ~ y)

grad_g <- makeFun(cbind(dx = dg_dx(x, y), dy = dg_dy(x, y)) ~ x & y)
grad_g(2,3)
     dx dy
[1,]  4 81

8 Optimization

8.1 Constrained Optimization

Plot contours and constraints together to visualize constrained optimization problems:

P <- makeFun(x^(0.2) * y^(0.8) ~ x & y) # objective function
Q <- makeFun(4*x + 3*y ~ x & y) # constraint function

contour_plot(
  P(x,y) ~ x & y, 
  domain(x=0:80, y=0:80), 
  contours_at = seq(20,80,5), # adding contours between 20 and 80 in increments of 5
  skip=0
) |>
  contour_plot(
    Q(x,y) ~ x & y, 
    contour_color="black", 
    contours_at = c(200), # constraint (contour line) of constraint function at z = 200
    lwd = 2
)
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
Scale for fill is already present.
Adding another scale for fill, which will replace the existing scale.

Zoom in for a better estimate and to approximate the Lagrange multiplier by changing the constraint by a small amount.


9 Integration

Approximate definite integrals by Riemann sums over an interval [a,b]:

f <- makeFun(x + sin(x^2) ~ x)

# define start point and end point of interval [a,b]
a <- 5 
b <- 10

n <- 100 # number of rectangles

base <- (b - a) / n # length of base of rectangle

# Left Riemann Sum
left_points <- seq(from = a, to = b - base, by = base)
left_heights <- f(left_points) # calculate the heights

left_areas <- base * left_heights

left_sum <- sum(left_areas)
left_sum 
[1] 37.44168
# Right Riemann Sum
right_points <- seq(from = a + base, to = b, by = base)
right_heights <- f(right_points) # calculate the heights

right_areas <- base * right_heights

right_sum <- sum(right_areas)
right_sum
[1] 37.67298
# Midpoint Riemann Sum
mid_points <- seq(from = a+base/2, to = b - base/2, by = base)
mid_heights <- f(mid_points) # calculate the heights

mid_areas <- base * mid_heights

mid_sum <- sum(mid_areas)
mid_sum
[1] 37.55494

Increase the number of rectangles for better accuracy.

Compute the true definite integral over an interval:

f <- makeFun(x + sin(x^2) ~ x)
Integrate(f(x) ~ x, domain(x=5:10)) # integrate f over the interval defined by x=a:b
Loading required namespace: cubature
[1] 37.55575

Find the antiderivative of a function:

f <- makeFun(x + sin(x^2) ~ x)

int_f <- antiD(f(x) ~ x)
int_f(5)
[1] 13.02792

10 Differential Equations

10.1 Slope Fields and Trajectories

Plot slope fields with vectorfield_plot() and solution trajectories with traj_plot():

vectorfield_plot(
  t ~ 1, 
  P ~ 6 - 2 * P, 
  domain(t=-8:8, P=-8:8)
)

diff_eq <- makeODE(dP ~ 6 - 2 * P)

soln <- integrateODE(diff_eq, domain(t=0:5), P = 6)
Solution containing functions P(t).
traj_plot(P(t) ~ t, soln, nt = 5)

Plot vector field + multiple trajectories:

diff_eq <- makeODE(dP ~ 6 - 2 * P)
soln1 <- integrateODE(diff_eq, domain(t=0:5), P = 6)
Solution containing functions P(t).
soln2 <- integrateODE(diff_eq, domain(t=0:5), P = 2)
Solution containing functions P(t).
traj_plot(P(t) ~ t, soln1, color="blue", nt=5) |>
  traj_plot(P(t) ~ t, soln2, color="magenta", nt=5) |>
  vectorfield_plot(t ~ 1, P ~ 6 - 2 * P, domain(t=0:5, P=0:8))


11 SIR Models

Use vectorfield_plot and makeODE to build SIR models:

a <- 0.001  # infection rate
b <- 0.2    # removal rate

vectorfield_plot(S ~ -a * S * I,
                 I ~  a * S * I - b * I,
                 domain(S = 0:800, I = 0:100),
                 transform = function(L) L^0.01)

SIR_diff_eq <- makeODE(dS ~ -a * S * I, dI ~ a * S * I - b * I)
SIR_soln <- integrateODE(SIR_diff_eq, domain(t = 0:80), S = 800, I = 5)
Solution containing functions S(t), I(t).
traj_plot(I(t) ~ S(t), SIR_soln, nt = 20)