To understand R and its maximum capabilities, let’s first think of R to function as a calculator. By default, R will read expressions following the order of operations; PEMDAS (Parentheses-Exponents-Multiplication-Division-Addition-Subtraction) or GEMS (Groupings-Exponents-Multiplication/Division-Subtraction/Addition). Later in this section, we will practice using parentheses to group expressions we want done in our desired order.
Addition: We use the + in order to add or sum values up.
2 + 2
## [1] 4Subtraction: We use the - to subtract or find the difference between values.
6 - 7
## [1] -1Multiplication: We use the * (asterisk) to multiply values.
4 * 3
## [1] 12Division: We use the / (forward slash) to divide values
2/3
## [1] 0.6666667Logarithms: By default, R reads the log function with base e (as a natural log) as opposed to common log with base 10 and uses log( ) to evaluate logarithms.
Review:
General Form: \(log_{a}(b) = x \Longrightarrow b=a^{x}\)
Common Log: \(log(10) = x \Longrightarrow 10 = 10^{x}\)
Natural Log: \(ln(10)=x \Longrightarrow 10=e^{x}\)
log(10)
## [1] 2.302585
#This will not output 1 but rather a value closer to e.
Although R uses base e by default, we can still define the base for the log function to change it from e to what we define it as.
log(10, base = 10)
## [1] 1
#Here I defined the base with a comma followed by "base = 10" and now we would expect this to output as 1 because the base is no longer e but is now 10.
log(10, 10)
## [1] 1
#Even bettter we can define the base by following with just a comma and then the base we want it defined as.
#Both operations should output as 1.Square Root: R uses sqrt( ) to evaluate SQUARE roots.
sqrt(16)
## [1] 4
sqrt(4)
## [1] 2
sqrt(6)
## [1] 2.44949Exponents: R uses ^ (caret symbol) to evaluate exponents.
2^2
## [1] 4
7^3
## [1] 343
2^37
## [1] 1.37439e+11
By default R can output numbers up to 7 digits total (or 6 digits after the decimal point) before it turns it into scientific notation.
\(2^{37}\) is equal to \(1.37439e+11\) which means \(1.37439 \times 10^{11}\) or \(137439000000\)
Bigger Roots/Fractional Exponents: Sometimes we want to find larger roots of numbers such as
\(\sqrt[3]{10}\) or \(\sqrt[5]{10^{2}}\)
We are able to compute larger roots if we first change these roots into fractional exponents.
Review:
General form: \(\sqrt[a]{b^{c}} = b^{\frac{c}{a}}\)
Therefore,
\(\sqrt[3]{10} = 10^{1/3}\) and \(\sqrt[5]{10^{2}} = 10^{2/5}\) . Since we know how to compute exponents in R, we can apply the same technique for fractional exponents. Be sure to encase your fractional exponent in parentheses so R knows how to read the operations the way you want it to.
10^(1/3)
## [1] 2.154435
10^(2/5)
## [1] 2.511886
8^(1/3)
## [1] 2e Raised to a Power: In order to evaluate something like:
\(e^{3}\) we do not write e^3. Instead we evaluate any e raised to a power x as exp(x).
Therefore, \(e^3\) in R is:
exp(3)
## [1] 20.08554Absolute Value: Absolute values can be expressed as abs( ).
abs(1)
## [1] 1
abs(-1)
## [1] 1Pi (3.14….): Pi is expressed as pi in R.
3*pi
## [1] 9.424778e (2.71….): We can express the constant e as exp(1).
exp(1) / 4
## [1] 0.6795705In addition to basic math operations, we can calculate more complex expressions in R. As mathematical expressions get more complicated, it is a good idea to use parentheses to group and let R know what should be done first in terms of operations.
Lets calculate the following in R:
\(\dfrac{(2 + 3)}{5}\)
(2+3)/5
## [1] 1
2+3/5
## [1] 2.6Notice: Although the expressions are exactly the same, the use of parentheses tells R what to do first. In the 1st expression, R will know to compute 2+3 then divide by 5 because we encased 2+3 in parentheses. As opposed to the 2nd expression where R will, by default, use the order of operations to calculate the expression. Thus, in the 2nd expression, R will compute 3/5 first then add 2 to that result.
\(\dfrac{5}{9} \times (40 - 32)\)
(5/9) * (40-32)
## [1] 4.444444The preceding expression is the conversion of temperature from degrees-Fahrenheit to degrees-Celsius, where 40 was the given temperature in degrees-Fahrenheit and R computed and outputted the temperature in degrees-Celsius. Later we will introduce defining objects/vectors (variables) to see how the same expressions can be easily computed, without having to continuously type the same expression and changing the input value.
\(|5-\sqrt{2} \left(\sqrt[3]{5^{5}} - 2\right)|\)
abs(5-(sqrt(2)*(5^(5/3)-2)))
## [1] 12.8475\(\dfrac{1}{\sqrt{2 \pi (3.1)^{2}}} e^{-\dfrac{(12-10.7)^{2}}{2(3.1)}}\)
(1/(sqrt(2 * pi * 3.1^2))) * exp(-((12-10.7)^2)/(2 * 3.1))
## [1] 0.09798692With evaluating larger expressions and using groupins (parentheses) will result in “+” when trying to run the code. The “+” most oftenly means that there is a mismatch and/or missing parentheses when using it for grouping. Be sure that parenheses match in terms of your groupings and there are no missing parentheses. If the issue still persists, you may restart R by going “Session” > “Restart R.” Then run your code again.
If you are having a difficult time computing more complex expressions like the one above, a helpful tip is to break the complex expressions into simpler expressions then combining them at the end. That way, we can see prematurely if our smaller codes and computations are running before running the bigger, complex expression.
(1/(sqrt(2 * pi * 3.1^2))) #1st Part of equation
## [1] 0.1286911
exp(-((12-10.7)^2)/(2 * 3.1)) #2nd part of equation
## [1] 0.761412
(1/(sqrt(2 * pi * 3.1^2))) * exp(-((12-10.7)^2)/(2 * 3.1)) #1st part multiplied by 2nd part
## [1] 0.09798692
When analyzing your data, it’s essential to keep a record of all commands and notes to retrace your steps later. In RStudio, create a script by selecting “File” > “New File” > “R Script.” This opens a new script window where you can type or paste commands (excluding the “>” prompt). Save the script to reuse it in the future by clicking on the “floppy-disk” logo at the top menu bar. It’s best to type and run commands from the script window to maintain a record of your session for easier replication.
In R, we can store information of various sorts by assigning them to objects. For example, if we want to create a object called x and give it a value of 4, we would write
x <- 4
The middle bit of this—a less than sign and a hyphen typed together to make something that looks a little like a left-pointing arrow—tells R to assign the value on the right to the object on the left. We can also use keyboard shortcuts to denote this symbol using: Alt + - (Windows) / Option + - (Mac). After running the command above, whenever we use x in a command it would be replaced by its value 4. For example, if we add 3 to x, we would expect to get 7.
x + 3
## [1] 7
We can always reassign a new value to a object. If we now tell R that x is equal to 32:
x <- 32
then x will update and take its new value.
x
## [1] 32
Just like a scalar (or single value object) we can create what we call a vector in which a single object has multiple values as oppose to a singular value. For example, what if we want to define the object y and give it values 1, 2, 3, 4, 5. We can achieve this by defining the object as we would with a singular value with our left-pointing arrow but embedding our set of values in c( ) and separating each value with a comma.
y = c(6, 7, 3, 4, 2)
This is very useful when we are inputting data manually into a data vector to put that vector in a data frame which we will talk about more in the next lab. Notice that in the environment, we now have an object y created with num [1:5] 1 2 3 4 5 assigned to this object. num represents the type of object it is in this case num is an abbreviation for numeric, which is a data type that represents numbers. [1:5] indicates that the vector contains 5 elements, with the first element (which is the value 6) indexed as the first element and the last (which is the value 2) as the fifth element.
If we define an object to be a vector with multiple values and do some computation with that object in an expression, it will not only output a single value, but it will out however many values there are in that vector because the transformation through the expression applies to all single vector value that we defined.
Let’s use the example with temperature conversion from degrees-Fahrenheit to degrees-Celsius:
\(C = \dfrac{5}{9} \times (F - 32)\)
Lets first appropriately define a vector with a set of temperature values in degrees-Fahrenheit:
temp.f <- c(67, 43, 78, 90, 81)
We then will write the expression conversion for degrees-Fahrenheit to degrees-Celsius replacing the degrees-Fahrenheit with our object name:
(5/9) * (temp.f - 32)
## [1] 19.444444 6.111111 25.555556 32.222222 27.222222
Notice that we have 5 values outputted. This is because R takes each value in temp.f vector and applies it to the conversion expression to get our degrees-Celsius. For example:
\(\dfrac{5}{9} (\textbf{67} - 32) = 19.444444\)
\(\dfrac{5}{9} (\textbf{43} - 32) = 6.111111\)
and so on so forth.
When naming your objects whether they be scalars or vectors, be sure that it is appropriate and that it easily represents the data that you are trying to use for analysis. Two main rules that we must follow when naming objects for R to read is to ensure that 1) Object names DO NOT have any spaces and 2) Object names DO NOT start with a number. One other thing to note is that R is case sensitive, in terms of object naming and defining. Meaning weight.lbs is not the same as Weight.lbs.
Here are a list of conventional and acceptable ways of naming objects: For the examples below we will refer to appropriately naming caterpillar lengths in centimeters.
Mixed Letter Cases: Can use capital letters for the first letter in every word and every other letter is lowercase
CaterpillarLengthCM <- c(3.288878, 9.788281, 4.408389, 6.508248, 7.137628, 2.025207)Underscores in Between Words: Can leave all letters lower-cased but inputs an underscore in between every word
caterpillar_length_cm <- c(3.288878, 9.788281, 4.408389, 6.508248, 7.137628, 2.025207)Periods in Between Words: Can leave all letters lower-cased but inputs a period in between every word
caterpillar.length.cm <- c(3.288878, 9.788281, 4.408389, 6.508248, 7.137628, 2.025207)If we include spaces or put a number first for our object names, we get an error. For example:
21CaterpillarLengthCM <- c(3.288878, 9.788281, 4.408389, 6.508248, 7.137628, 2.025207)
Caterpillar Length CM <- c(3.288878, 9.788281, 4.408389, 6.508248, 7.137628, 2.025207)
If you try running it yourself in R, it will output an error message.
Last lab, we touched bases on defining objects and one thing we introduced briefly were vectors. We can create what we call a vector in which a single object has multiple values as oppose to a singular value. We define a vector by using the c(x, y, z) function, where x, y, and z represent the values we want to store in that vector.
Let us define an object called temperatureF by storing the values 78, 85, 64, 54, 102, and 98.6, which will represent the temperature in degrees-Fahrenheit, in that object:
library(tinytex)
## Warning: package 'tinytex' was built under R version 4.5.2
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.2
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# Creating an object of recorded temperatures in degrees-Fahrenheit.
temperatureF <- c( 78, 85, 64, 54, 102, 98.6)
# Prints the created object.
temperatureF
## [1] 78.0 85.0 64.0 54.0 102.0 98.6
The power and usefullness of vectors is that sometimes R can do the same calculation on all elements of a vector with one command, and we played around with this power last lab. For example, to convert a temperature in Fahrenheit to Celsius, we would want to subtract 32 and multiply times 5/9. We can do that for all the numbers in this vector at once:
\(\dfrac{5}{9} \times (\text{temperatureF}- 32)\)
# Creates an object that stores the output of the resulting conversion calculation with recorded temperatures in degrees-Fahrenheit as the input.
temperatureC <- (5/9)*(temperatureF - 32)
# Prints the temperatures in Celsius.
temperatureC
## [1] 25.55556 29.44444 17.77778 12.22222 38.88889 37.00000
If you want to pull out a specific number from a vector list, we would us [x], brackets, where x denotes the index of the value you want to pull out.
# Pulls out the 3rd value in the temperatures in Cesius object.
temperatureC[3]
## [1] 17.77778
# Pulls out the 5th value in the temperatures in Cesius object.
temperatureC[5]
## [1] 38.88889
Be careful with the difference between ( ) parentheses and [ ] brackets and using them in R.
Vectors are mathematical objects that store multiple values, and you can perform operations directly on these values. Instead of extracting individual values from a vector for calculations, we can apply functions and operations to the entire vector at once. This makes calculations more efficient and simplifies coding when working with large datasets. This is especially useful if we want to perform some statistical analysis on a set of values (i.e. Finding the mean) or to inevstigate what our objects, or variables, look like.
Mean: We use the function mean(x), where x is the object (vector) we want to find the mean of.
mean(temperatureC)
## [1] 26.81481Sum: We use the function sum(x), where x is the object (vector) we want to find the sum of.
sum(temperatureC)
## [1] 160.8889Length: We use the function length(x), where x is the object (vector) we want to find the length of, or how many values/ elements are in that object.
length(temperatureC)
## [1] 6If you wanted to remove the whole list of objects in your environment, you would click on the “broom” icon button to clear the whole environment. However, if you would like to remove certain objects you may use either remove( ) or rm( ) with the objects you want to remove inside the parentheses (If you have multiple objects you would like to remove, separate them with a comma).
x = c(1, 2, 3, 4, 5)
y = c(6, 7, 8, 9, 10)
remove(x)
remove(x, y)
## Warning in remove(x, y): object 'x' not found
Packages in R are collections of functions, data,
and documentation bundled together to extend R’s capabilities. They
allow users to perform specialized tasks (e.g., data manipulation,
visualization, machine learning) that aren’t available in base R.
Popular packages include ggplot2 (for visualization),
dplyr (for data manipulation), and caret (for
machine learning). There are a bunch of packages, but it is up to you to
decide what package to install to make your objective with R more
efficient. You can find a bunch on the web.
We can install a package using the install.packages()
function. Let us install the package dplyr, which
allows for easy modification of data frames, since we
will be using it for this lab.
Once a package is installed, it needs to be loaded into R during a session if you want to use it. You do this with a function called library( ).
library(dplyr)
*If you are getting an error, that means the package is not installed yet.
A working directory in R is the folder or location on your computer where R reads and saves files by default. It’s like R’s “home base” for finding and storing files.
A file path defines the location of a file or
directory on your computer. It shows the path that leads from the root
directory (like C:\ on Windows or / on
Linux/macOS) to the file or folder you want to work with.
Windows:
C:\Users\YourName\Documents\file.csv
macOS/Linux:
/Users/YourName/Documents/file.csv
Open your file explorer (Windows Explorer, Finder, etc.).
Find the file or folder you would like to refer to or save in.
Right-click on the file and select “Properties” (Windows) or “Get Info” (macOS)/ or hold Opt and copy path (macOS), and copy the location.
Add the file name (if it’s a file) at the end of the location.
If you are using windows, the file path will not read into R if you have a \ (backwards slash). We can do a few things to fix this:
We can change all the \ (backwards slashes) into / (Forward Slashes). OR
We can add another \ (backwards slashes) to the already existing backward slashes so you have two \\ (Backward Slashes).
You can check your current working directory using getwd( ).
You can also set your working directory if it currently is not the file path that you want with setwd( ), with your desired file path inside the parentheses.
Here for practice we set our working directory to refer to the labs, but then again working directories are supposed to be personal and to your desired way of referring or saving to a file.
Previously (perhaps in older versions of R), we used to be able to set a working directory for reference if you wanted to pull out a data set located in a file path. That way when we read in a data set, we do not necessarily have to type in the working directory path but just the data set title alone to read the data set. Unfortunately now we have to use more complex ways of first setting working directory and calling a data set directly from that directory using an external package and a new command, which I will go over in another lab. For now, in order to read a data set, we need to copy the whole file path with the data set attached and read that into R (See next section).
Sometimes, we already have a data set we want to work with from an external file. We can call this data into R so that we can work with it in R. In these labs, we have saved the data in a “comma-separated variable” format, CSV for short.
For example in this lab, let’s use a data set about the passengers of the RMS Titanic. One of the data sets in the folder that we downloaded in the first week is called “titanic.csv”. This is a data set of 1313 passengers from the voyage of this ship, which contains information about some personal info about each passenger as well as whether they survived the accident or not.
To import a CSV file into R, we use the read.csv() function as in the following command (We will use the full file path to the titanic data set).
titanicData <- read.csv('/Users/michaelcajigal/UOG Instructor Folder/FA2026/BI412L/ABDLabs/ABDLabs/DataForLabs/titanic.csv', stringsAsFactors = TRUE)
This looks for the file called titanic.csv in the folder called DataForLabs. Here we have given the name titanicData to the object in R that contains all this passenger data.
stringsAsFactors Does:When set to TRUE, any character
columns in a data frame are automatically converted into
factors. Factors are categorical variables with a
predefined set of levels (unique values).
When set to FALSE (which is now the
default behavior in recent versions of R), character columns remain as
character strings.
To see if the data loads appropriately, we might want to run the command summary( ). This will give a summary of the data file that we are reading.
summary(titanicData)
## passenger_class name age
## 1st:322 Carlsson,MrFransOlof : 2 Min. : 0.1667
## 2nd:280 Connolly,MissKate : 2 1st Qu.:21.0000
## 3rd:711 Kelly,MrJames : 2 Median :30.0000
## Abbing,MrAnthony : 1 Mean :31.1942
## Abbott,MasterEugeneJoseph: 1 3rd Qu.:41.0000
## Abbott,MrRossmoreEdward : 1 Max. :71.0000
## (Other) :1304 NA's :680
## embarked home_destination sex survive
## :493 :558 female:463 no :864
## Cherbourg :202 NewYork,NY : 65 male :850 yes:449
## Queenstown : 45 London : 14
## Southampton:573 Montreal,PQ : 10
## Cornwall/Akron,OH: 9
## Paris,France : 9
## (Other) :648
Sometimes we would like to add a new column to a data frame. The easiest way to do this is to simply assign a new vector to a new column name, using the $.
For example, to add the log of age as a column in the titanicData data frame, we can write:
titanicData$log_age = log(titanicData$age)
The head( ) command allows us to see the first 6 rows of data entries in a data frame. Of course we can specify how many rows we want to see using a comma followed by the number of rows desired in the head ( ) command.
You can run the command head(titanicData) to see that log_age is now a column in titanicData.
# Gets first 6 rows.
head(titanicData)
## passenger_class name age embarked
## 1 1st Allen,MissElisabethWalton 29.0000 Southampton
## 2 1st Allison,MissHelenLoraine 2.0000 Southampton
## 3 1st Allison,MrHudsonJoshuaCreighton 30.0000 Southampton
## 4 1st Allison,MrsHudsonJ.C.(BessieWaldoDaniels) 25.0000 Southampton
## 5 1st Allison,MasterHudsonTrevor 0.9167 Southampton
## 6 1st Anderson,MrHarry 47.0000 Southampton
## home_destination sex survive log_age
## 1 StLouis,MO female yes 3.36729583
## 2 Montreal,PQ/Chesterville,ON female no 0.69314718
## 3 Montreal,PQ/Chesterville,ON male no 3.40119738
## 4 Montreal,PQ/Chesterville,ON female no 3.21887582
## 5 Montreal,PQ/Chesterville,ON male yes -0.08697501
## 6 NewYork,NY male yes 3.85014760
# Gets first 10 rows.
head(titanicData, 10)
## passenger_class name age
## 1 1st Allen,MissElisabethWalton 29.0000
## 2 1st Allison,MissHelenLoraine 2.0000
## 3 1st Allison,MrHudsonJoshuaCreighton 30.0000
## 4 1st Allison,MrsHudsonJ.C.(BessieWaldoDaniels) 25.0000
## 5 1st Allison,MasterHudsonTrevor 0.9167
## 6 1st Anderson,MrHarry 47.0000
## 7 1st Andrews,MissKorneliaTheodosia 63.0000
## 8 1st Andrews,MrThomas,jr 39.0000
## 9 1st Appleton,MrsEdwardDale(CharlotteLamson) 58.0000
## 10 1st Artagaveytia,MrRamon 71.0000
## embarked home_destination sex survive log_age
## 1 Southampton StLouis,MO female yes 3.36729583
## 2 Southampton Montreal,PQ/Chesterville,ON female no 0.69314718
## 3 Southampton Montreal,PQ/Chesterville,ON male no 3.40119738
## 4 Southampton Montreal,PQ/Chesterville,ON female no 3.21887582
## 5 Southampton Montreal,PQ/Chesterville,ON male yes -0.08697501
## 6 Southampton NewYork,NY male yes 3.85014760
## 7 Southampton Hudson,NY female yes 4.14313473
## 8 Southampton Belfast,NI male no 3.66356165
## 9 Southampton Bayside,Queens,NY female yes 4.06044301
## 10 Cherbourg Montevideo,Uruguay male no 4.26267988
Sometimes we want to do an analysis only on some of the data that fit certain criteria. For example, we might want to analyze the data from the Titanic using only the information from females.
The easiest way to do this is to use the filter( ) function from the package dplyr. (Make sure you have sourced the dplyr package as described above, and then load it into R using library( )):
library(dplyr)
In the titanic data set there is a variable named sex, and an individual is female if that variable has value “female”. We can create a new data frame that includes only the data from females with the following command:
titanicDataFemalesOnly <- filter(titanicData, sex == "female")
This new data frame will include all the same columns as the original titanicData, but it will only include the rows for which the sex was “female”.
Note that the syntax here requires a double == sign. In R (and many other computer languages), the double equal sign creates a statement that can be evaluated as true or false, while a single equal sign may change the value of the object to the value on the right-hand side of the equal sign. Here we are asking, for each individual, whether sex is “female”, not assigning the value ”female” to the variable sex. So we use a double equal sign ==.
Comments
In scripts, it can be very useful to save a bit of text which is not to be evaluated by R. You can leave a note to yourself (or a colleague) about what the next line is supposed to do, what its strengths and limitations are, or anything else you want to remember later. To leave a note, we use “comments”, which are a line of text that starts with the hash symbol # (Hash tag). Anything on a line after a # will be ignored by R.