77. More function stuff - rep, sort, seq, colon operator
7.1 More about the rep function.
###########################################################.## More about the rep function.############################################################.# The rep function can be used in several ways.# In the simplest use of the rep function, rep returns a vector# that contains the values from the first argument to the function# repeated the number of times specified in the 2nd argument. # Examples:# Repeat the number 3 five timesrep(3, 5)
[1] 3 3 3 3 3
# repeat the number 5 three times:rep(5, 3)
[1] 5 5 5
# View the help page by typing: ## ?rep # see the documentation for rep function# since the rep function returns a vector, you can do anything with the# return value that you can do with any other vectorthreeFives <-rep(5,3)threeFives
[1] 5 5 5
threeFives *10
[1] 50 50 50
# The default value for the number of repetitions is 1 (i.e. one)rep(100) # same as 100 ... why would you do this ??? you probably wouldn't ... yet ...
[1] 100
# You can use rep to repeat entire vectorsnums <-c(10,20,30,40)rep(nums, 2) # 10 20 30 40 10 20 30 40
[1] 10 20 30 40 10 20 30 40
7.1.1 times argument
########################################################################.# Other arguments of the rep function.## The "Details" section of the rep documentation shows the # following:## rep(x, times = 1, length.out = NA, each = 1)## See the "Arguments" section of the rep documentation for# an explanation of what each of the arguments mean.########################################################################.# Let's start with some data:nums <-c(10,20)nums # show the value in nums
[1] 10 20
# The rep documentation shows the following:## rep(x, times = 1, length.out = NA, each = 1)## "x" is the first argument - "x" is the vector that will be repeated.# "times" is the 2nd argument - "times" is the number of times to repeat "x" (default is 1 time)## Therefore the following are the same thing:rep(nums, 5) # 5 is the value of 2nd argument to rep
[1] 10 20 10 20 10 20 10 20 10 20
rep(x=nums, times=5) # same thing - specify 5 as the value of the "times" argument
[1] 10 20 10 20 10 20 10 20 10 20
rep(times=5, x=nums) # same thing - specify 5 as the value of the "times" argument
[1] 10 20 10 20 10 20 10 20 10 20
7.1.2 length.out argument
#--------------------------------------------------------.# rep ( SOME_VECTOR, length.out=SOME_NUMBER )## is the same as## rep_len ( SOME_VECTOR, SOME_NUMBER )#--------------------------------------------------------.# The length.out argument causes the values in the x argument, i.e. the 1st argument, to be repeated to the specified length. ####nums # nums didn't change
[1] 10 20
rep(nums, length.out=5) # repeat the values in nums to a length of 5
[1] 10 20 10 20 10
# The rep_len is just a shorthand for using the length.out argument in the rep function ##### to accomplish the same thingnums # show the values in nums
[1] 10 20
rep(nums, length.out=5) # repeat the values in nums to a length of 5
[1] 10 20 10 20 10
rep_len(nums,5) # same thing, another way
[1] 10 20 10 20 10
rep(nums, length.out=15) # repeat the values in nums to a length of 15
[1] 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10
rep_len(nums,15) # same thing, another way
[1] 10 20 10 20 10 20 10 20 10 20 10 20 10 20 10
7.1.3 each argument
#-----------------------------------------------------------.# rep ( SOME_VECTOR, each = SOME_NUMBER )#-----------------------------------------------------------.# The each argument causes each value the x argument to be repeated sequentially the specified number of times ####nums # show the values in nums
[1] 10 20
rep(nums, each=5) # repeat each value of nums 5 times ####
[1] 10 10 10 10 10 20 20 20 20 20
#-----------------------------------------------------------------------------------------.# Sometimes it's hard to know what a function will do. The help page# doesn't really explain what will happen for all the different possible combinations of # the arguments, times, length.out and each.## We can experiment to find out ...#-----------------------------------------------------------------------------------------.
#######################################################################################.# Understanding R's help files ###### R functions can be used in many many different ways. You must become familiar with # the R help files in order to understand how each function can be used. ## Pay attention to the following in the R help files## - what arguments can be specified## - what are the names of the arguments## - what are the default values (if any) of the arguments. The default values of# an argument appear after an = sign next to the argument in the help file.## - how the function works when different arguments are specified#######################################################################################.
7.3 sort function
############################################################################.## sort( SOME_VECTOR ) # returns the vector sorted in increasing oder ###### sort( SOME_VECTOR, decreasing=TRUE ) # returns the vector sorted in decreasing order #################################################################################.grades =c(93, 76 , 69, 83, 77, 98, 100, 25, 89, 92, 91, 52)grades
[1] 93 76 69 83 77 98 100 25 89 92 91 52
sort(grades) # show the grades in sorted order, i.e. 25 52 69 76 ... etc
[1] 25 52 69 76 77 83 89 91 92 93 98 100
# The variable grades is still in the original ordergrades # the variable grades is still in the original order
[1] 93 76 69 83 77 98 100 25 89 92 91 52
# REMEMBER - as always, if you want to change a variable, you MUST use an# assignment statement.## If you want to change the value of the grades variable, then you must# assign the result back to the grades variable. grades=sort(grades) # now the variable grades contains the sorted valuesgrades
[1] 25 52 69 76 77 83 89 91 92 93 98 100
#---------------------------------------------------------------------.# The decreasing argument may be TRUE or FALSE (default is FALSE) #####---------------------------------------------------------------------.sort(grades, decreasing =FALSE) # same thing (default for decreasing is FALSE)
[1] 25 52 69 76 77 83 89 91 92 93 98 100
sort(grades, decreasing =TRUE)
[1] 100 98 93 92 91 89 83 77 76 69 52 25
# See the help page for advanced options that can be used with sort## ?sort
7.4 More about the seq function.
############################################################################.## More about the seq function. #################################################################################.# Review of the basic use of seq# We already covered the following:## ?seq # see the help page for seqseq(from=8, to=10) # 8 9 10 count up
[1] 8 9 10
seq(from=10, to=8) # 10 9 8 count down
[1] 10 9 8
seq(10,8) # 10 9 8 - same thing - the names aren't necessary if you write the arguments in the expected order
[1] 10 9 8
# ... seq can also accept other arguments:#-----------------------------------------------------------------------------.# seq( ... by=SOME_POSITIVE_OR_NEGATIVE_NUMBER .... ) ###### The by argument tells seq what number to "count by". (by can be positive or negative) ###### 1st value in the output vector is the "from" value.# 2nd value in the output vector is "from" + "by"# 3rd value in the output vector is "from" + "by" + "by"# 4th value in the output vector is "from" + "by" + "by" + "by"# etc ...## By default, the value of by is 1.## See examples below. #-----------------------------------------------------------------------------.# count by threes ... up until but not past the to valueseq(from=20, to=30, by=3) # 20 23 26 29
[1] 20 23 26 29
# To count down by any number other than 1 you must use a negative value for by.# # In the following command we count down# from 10 to 3 by threes, so by must be MINUS three (i.e. by = -3)seq(from=30, to=20, by=-3) # 30 27 24 21 count down by threes
[1] 30 27 24 21
# if you use the wrong sign (+ or -) for by you'll get an error#seq(from=30, to=20, by=3) # ERROR - counting down - must have negative value for by#seq(from=20, to=30, by=-3) # ERROR - counting up - must have positive value for by#-----------------------------------------------------------------------------.# The return value of seq always starts with the "from" value and goes no further than the "to" value. ###### NOTE that the result might not actually include the "to" value if the "to" value# doesn't naturally arise from the implied sequence.## See the examples below.#-----------------------------------------------------------------------------.seq( from =10 , to =20, by=4 ) # 10 14 18 - result does NOT include 20.
[1] 10 14 18
#-----------------------------------------------------------------------------.## the arguments "from" and "to" do NOT have to be whole numbers ######-----------------------------------------------------------------------------.seq( from = .5, to =3.5) # 0.5 1.5 2.5 3.5
[1] 0.5 1.5 2.5 3.5
seq( from =0.75 , to =3 ) # 0.75 1.75 2.75 - result does NOT include 3. ####
[1] 0.75 1.75 2.75
7.5 — PRACTICE —
#########################################################################.# QUESTION #############################################################################.# Write code to generate the number -5 until -200 but no further. Count down by 5's# The code should produce# -5 -10 -15 .... -200#########################################################################.
#########################################################################.# QUESTION #############################################################################.# # Based on the documentation for seq, what will the following command display?## > seq() # what will this display???# # How did you figure out your answer from the documentation?#########################################################################.
Click here for the answer
# ANSWER - just try it - it shows 1 - can you understand why? # See the documentation ?seqseq()
[1] 1
7.6 Even more about the seq function.
#-----------------------------------------------------------------------------.# Other arguments:## length.out - total length of the resulting vector## along.with - specify a vector whose length should be used as the length of the result## See examples below#-----------------------------------------------------------------------------.# View the help page by typing: ## ?seq# from,to,length.out (without by) - start with from, end with to, total of 5 numbersseq( from=1, to=2, length.out=5) #
[1] 1.00 1.25 1.50 1.75 2.00
# from,by,length.out (without to) - start with from, keep adding by, for a total of length.out numbersseq(from=2, by=3, length.out=20) # start from 2, add 3 each time until you get 20 numbers
#-----------------------------------------------------------------------------.# QUESTION: What will the following produce ? ## I guess you can run it to find out but you should know how to answer this # WIHTOUT needing to run the code.#-----------------------------------------------------------------------------.seq(2, 3, length.out=20)
# to,by,length.out (without from)seq(to=100, by=3, length.out=4) # generate 4 numbers each one 3 greater than the next until you get to 100
[1] 91 94 97 100
#-----------------------------------------------------------------------------.# QUESTION: What will the following produce ? ## See if you can figure out what each of the following will# display BEFORE running the command#-----------------------------------------------------------------------------.seq(from=2, to=3, by=0.2)
#--------------------------------------------------------------------.## length.out argument ######--------------------------------------------------------------------.# length.out is similar to the length.out for the rep function.# If you specify length.out you do not have to specify the to argumentseq(3, length.out=7, by=-1) # 3 2 1 0 -1 -2 -3
[1] 3 2 1 0 -1 -2 -3
seq(3, length.out=7) # 3 4 5 6 7 8 9
[1] 3 4 5 6 7 8 9
seq(3, length.out=7, by=-2) # 3 1 -1 -3 -5 -7 -9
[1] 3 1 -1 -3 -5 -7 -9
seq(3, length.out=7, by=10) # 3 13 23 33 43 53 63
[1] 3 13 23 33 43 53 63
7.6.2 along.with=SOME_VECTOR
#--------------------------------------------------------------------.## along.with=SOME_VECTOR ###### This argument is the same as length.out=length(SOME_VECTOR)## see examples below#--------------------------------------------------------------------.# Example: suppose a professor wanted to give a curve so that people# with lower grades got a higher curve.# # The professor could do the following:# Here are the original gradesgrades =c(98,77,64,79,76, 84, 92, 78)grades
[1] 98 77 64 79 76 84 92 78
length(grades) # how many grades are there?
[1] 8
# Sort the grades in decreasing ordersortedGrades =sort(grades, decreasing=TRUE)sortedGrades
[1] 98 92 84 79 78 77 76 64
# Generate a vector with the amount to curve each grade.# Highest grade has a curve of 1 point, 2nd highest grade has a curve# of 2 points, etc.curveAmounts =seq(from=1, along.with=sortedGrades)curveAmounts
[1] 1 2 3 4 5 6 7 8
curvedGrades = sortedGrades + curveAmountssortedGrades # original grades
[1] 98 92 84 79 78 77 76 64
curvedGrades # curved grades
[1] 99 94 87 83 83 83 83 72
7.7 Skipping arguments
#############################################################################.# You can skip an argument by repeating commas.# This works but it is not usually how R programmers write code. Therefore# others might not understand your code if you do this. You should know # that it works but I recommend that you don't do it in practice. #############################################################################.# value of 1st argument (ie. "from") is 2# value of 2nd argument (ie. "to") is 3seq(2, 3, length.out=20)
# value of 1st argument (ie. "from") is 2# value of 2nd argument (ie. "to") is blank - i.e. the default is used# value of 3rd argument (ie. "by") is 3 - i.e. the default is usedseq(2, , 3, length.out=20) # now the 3 is being passed to 3rd argument, ie. by
#######################################################.# QUESTION ###### A professor wants to curve the grades of his students. # The grades are in the variable named grades.## The highest grade should get a 1 point curve, # ... the next lower grade a 3 point curve# ... the next lower grade a 5 point curve# etc.## Write R code to store the curved grades in a variable named curvedGrades.# Your code should work unchanged no matter what values are stored in# the grades vector.## EXAMPLE 1# > grades = c(98,77,64,79,76, 84, 92, 78)# > # YOUR CODE GOES HERE# > curvedGrades# [1] 99 95 89 86 87 88 89 79## EXAMPLE 2# > grades = c(70, 90, 60, 80)# > # YOUR CODE GOES HERE# > curvedGrades# [1] 91 83 75 67#######################################################.
Click here for the answer
# Start by thinking about the answer this way: # ANSWER# 1. Sort the grades into decreasing order # ANSWER# 2. Generate the sequence 1,3,5,... etc # ANSWER# 3. Now add part (1) to part (2) to get the answer # ANSWER## The following is not the answer yet, but shows how we want to # ANSWER# build up to the final answer. # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78) # ANSWERgrades =sort(grades, decreasing=TRUE) # ANSWERcurvedGrades = grades +c(1,3,5,7,9,11,13,15) # ANSWERcurvedGrades # ANSWER
[1] 99 95 89 86 87 88 89 79
# The previous code works if you know exactly how many grades there are. # ANSWER# However, your code should work, unchanged, for any value of the grades # ANSWER # vector. # ANSWER# Use the seq function to generate the c(1,2,3 ... etc) vector # ANSWER# This can be done in two different ways. # ANSWER# (a) with the along.with argument of seq # ANSWER# (b) with the along.with length.out argument seq and length function # ANSWER# This is the code for (a) # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78) # ANSWERgrades =sort(grades, decreasing=TRUE) # ANSWERcurvedGrades = grades +seq(from=1, by=2, along.with=grades) # ANSWERcurvedGrades # ANSWER
[1] 99 95 89 86 87 88 89 79
# This is the code for (b) # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78) # ANSWERgrades =sort(grades, decreasing=TRUE) # ANSWERcurvedGrades = grades +seq(from=1, by=2, length.out=length(grades)) # ANSWERcurvedGrades # ANSWER
[1] 99 95 89 86 87 88 89 79
#######################################################.# QUESTION ###### Do the same as the previous question, however, this time# the professor wants to give the highest 25% of the class no curve.# The first grade below the highest 25% of the class a 1 point curve, # ... the next lower grade a 3 point curve# ... the next lower grade a 5 point curve# etc.## EXAMPLE 1 # > grades = c(98,77,64,79,76, 84, 92, 78)# > # YOUR CODE GOES HERE# [1] 98 92 85 82 83 84 85 75## EXAMPLE 2# > grades = c(70, 90, 60, 80)# > # YOUR CODE GOES HERE# [1] 90 81 73 65########################################################.
Click here for the answer
# Start with some data # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78) # ANSWER# Think about it this way - we need to curve the following # ANSWER# grades in the following way: # ANSWER## SORTED GRADES: 98 92 84 79 78 77 76 64# CURVE: 0 0 1 3 5 7 9 11# We can accomplish this with the following code: # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78) # ANSWERgrades =sort(grades, decreasing=TRUE) # ANSWERgrades # ANSWER
# Some people, might write the code all in one line. # ANSWER# I don't recommend that in this case - it's too confusing. # ANSWER# However, you should be able to READ code like this # ANSWER# as you WILL SEE code like this written by others. # ANSWER# To help you understand the code you can highlight # ANSWER# portions of the line and press ctrl-ENTER or cmd-ENTER # ANSWER# to run just those portions of the code. # ANSWER# Practice on the following to make sure you understand # ANSWER# how to read code like this and understand it. # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78)grades =sort(grades, decreasing=TRUE)grades
#################################################################.# QUESTION ##### # This time make the curve amounts the square root of 100-grade for each # person's grade. All students should get this curve.## EXAMPLE 1# > grades = c(100, 99, 96, 91, 84, 75, 19, 0)# # YOUR CODE GOES HERE# [1] 100 100 98 94 88 80 28 10### EXAMPLE 2# > grades = c(98,77,64,79,76, 84, 92, 78)# # YOUR CODE GOES HERE# [1] 99.41421 81.79583 70.00000 83.58258 80.89898 88.00000 94.82843 82.69042#################################################################.
# ANSWER# (this answer is all in one line of code) # ANSWERgrades =c(98,77,64,79,76, 84, 92, 78) # ANSWERcurvedGrades = grades +sqrt(100-grades) # ANSWERcurvedGrades # ANSWER
7.9 Practice with NESTING functions one inside the other
#################################################################.# QUESTION ###### create a vector that contains the even #rs from 2 through 30 followed by # the odd #rs from from 1 through 30. Write your command using the least amount# of typing possible.## The result should be as shown below. ## > # YOUR COMMAND GOES HERE## [1] 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29#################################################################.
#################################################################.# QUESTION ###### Use R's functions that we learned about to # create a vector of the evens from 2 through 10 repeated to a length of 27# DO NOT SIMPLY JUST TYPE THE NUMBERS IN A c(). One or more functions other than just c().## The result should be as shown below. ## > # YOUR COMMAND GOES HERE## [1] 2 4 6 8 10 2 4 6 8 10 2 4 6 8 10 2 4 6 8 10 2 4 6 8 10 2 4#################################################################.
#################################################################.# QUESTION ###### Generate a vector that contains the even #rs from 1 through 10 # followed by the odd #rs from 1 through 10.# All of these numbers should be repeated 3 times# # The output should look like this:## > # YOUR COMMAND GOES HERE## [1] 2 4 6 8 10 1 3 5 7 9 2 4 6# [14] 8 10 1 3 5 7 9 2 4 6 8 10 1# [27] 3 5 7 9## MAKE SURE YOU# - use the c function when necessary to combine the evens and odds into a single vector# - put the commas in the correct place# - put all parentheses in the correct places#################################################################.
#################################################################.# QUESTION ###### Create vector that has the numbers 0.3, 0.6, 0.9, 1.2, 1.5 ... for a total of 300 values#################################################################.
7.10 The : operator
#----------------------------------------------------------------------------.# The : operator is a shorthand for a basic usage of the seq function that only uses from and to arguments ###### For example:# # > 3:6 # is the same as seq(from=3, to=6)# # [1] 3 4 5 6## See more examples below.#----------------------------------------------------------------------------.3:5# 3 4 5
[1] 3 4 5
seq(3,5) # 3 4 5 (same thing)
[1] 3 4 5
5:3# 5 4 3
[1] 5 4 3
seq(5,3) # 5 4 3 (same thing)
[1] 5 4 3
-3:5# -3 -2 -1 0 1 2 3 4 5
[1] -3 -2 -1 0 1 2 3 4 5
seq(-3,5) # -3 -2 -1 0 1 2 3 4 5 (same thing)
[1] -3 -2 -1 0 1 2 3 4 5
3:-5# 3 2 1 0 -1 -2 -3 -4 -5
[1] 3 2 1 0 -1 -2 -3 -4 -5
seq(3,-5) # 3 2 1 0 -1 -2 -3 -4 -5 (same thing)
[1] 3 2 1 0 -1 -2 -3 -4 -5
7.11 Order of operations in R
###########################################################################.# Order of operations in R ###### To see the full list of the order of operations for R (or "operator precedence")# type the following (notice the CAPITAL "S" in ?Syntax).## ?Syntax # Operators that appear higher in the list are done first. ###### or see the following webpage:## https://stat.ethz.ch/R-manual/R-devel/library/base/html/Syntax.html###########################################################################.# Let's look at the complete order of operations for R's operators.# as mentioned above operators that appear higher in the list are done # before operators that appear lower in the list. # View the help page by typing: ## ?Syntax# Notice that the colon operator is done AFTER exponentiation but# BEFORE multiplication, division, addition and subtraction are done!## Be careful of the order of operations!# The colon operator is done BEFORE the subtraction operator15-4:2# result is 11 12 13 (might not be what you would have thought)
[1] 11 12 13
#original: 15-4:2# colon is first: 15-c(4,3,2)# minus is next: c(15-4, 15-3, 15-2)# c(11, 12, 13)(15-4):2# this is different
[1] 11 10 9 8 7 6 5 4 3 2
#original: (15-4):2# minus first: 11:2# colon is next: c(11,10,9,8,7,6,54,4,3,2)# View the help page by typing: ## ?Syntax
7.12 Help pages for R’s operators
#------------------------------------------------------------------.## ?`:` # type this to see the help page for the colon operator (e..g 3:5) ##### #------------------------------------------------------------------.# To get more info about the colon operator, # you can read the R help documentation for the : operator.## To do so, you must enclose the colon in `backticks` (also known as `grave accents`).# The backtick (or grave accent) character is on most USA keyboards# in the upper left hand corner under the ESC key.# It is on the same key as the "~" (tilde) character. # ?`:` # You must enclose the colon in `backticks` (also known as `grave accents`) ##### help(`:`) # this does the same thing# If you leave out the `backticks` (AKA `grave accents`) you will get an error.# Note the red "x" in the left margin in RStudio next to the following command.## ?: # ERROR# You can also use backticks for help topics that contain other symbols or spaces## ?`+` # Shows help topic for + (and other arithmetic operators)#############################################################################.# The following was added in 2022# NOTE - in recent versions of R, in addition to `backticks`# 'single quotes' (i.e. 'apostrophes')# and "double quotes" (i.e. "quotes")# also work.#############################################################################.# as of 2022, 'single quotes' "double quotes" and `backticks` all work## ?':' # single quotes# ?":" # double quotes# ?`:` # backticks## ?'+' # single quotes# ?"+" # double quotes# ?`+` # backticks