More Useful Functions
The purpose of this project is to look at some more useful functions that are part of R and to practice some of the things you've learned previously. Each task addresses separate features of R, so you should keep your code organized by encapsulating the code for each task into one or more functions. For example, the first function required in task 1 is FixMixed_v1, so you will begin with code like this:
fixMixed_v1 <- function( ) {
# code for task 1B goes here
# have the function return the data frame created/read in this function
}
Project Tasks
-
Eventually, we all have to deal with reading in data that has missing values or that R interprets differently from how we want to use it. There are many functions we can use to explore our data, making sure it matches what we want. In cases where it does not, we can either manually fix the problems or try adding arguments to the read function that avoid the problems.
- Download the file mixed.csv. Store it in the same directory as your project4.R file. Set the working directory to your source file location.
- Create a function called fixMixed_v1 to encapsulate this task, as specified above. Add code to the function and test it by completing the following sub-tasks.
- This function is specific to a particular data file and it will achieve a particular goal, namely ensuring the Apple column is numeric. It is good practice to use a function name that indicates the function's purpose (which we do here - sort of - we specify that the file is mixed and that we are fixing it up, but not what or how we are fixing it up - also we indicate that it is the first version of the function with v1). It is also good practice to write a comment at the beginning of each function, indicating what it does and what it returns. Add this comment before writing any code:
# Read in mixed.csv and change the $Apple column to be all numeric. # Return the dataframe with the adjusted data.
- Assign to a variable the data frame generated by calling the
read.csv()function to read the mixed.csv file. - Print the result of calling the
str()function with the data frame as the argument to print out a representation of the data frame. - Add a call to fixMixed_v1 at the bottom of the file and Source the file to run it and test it.
- Print the result of calling the
summary()function on the data frame to print out a summary of the data in the data frame. - Source the code to test it again.
- Use a for loop to loop over the columns of the data frame. You can do this using either syntax below.
#option 1 for( column in myDataFrame ) { # code to repeat goes here, column refers to each column in turn } #option 2 for(i in 1:length(myDataFrame) ) { # code to repeat goes here, myDataFrame[[i]] refers to each column in turn }Each time through the loop, print the result of applying the
class()and thetypeof()functions to the current column. Note that three of the columns are character strings, including the first one. See if you can write out the name of each column along with its class and type (it's easier to use the second option for loop to do this). - Source the code to test it again.
- Now, we finally again to the stated purpose of the function. Re-assign the "Apple" column to be numeric. To do this, you have to first convert the column to a character column using
as.character(), then convert the column to a double column usingas.double(). You can compose the two functions and assign the result back to the "Apple" column in a single line. - On the last line, return the data frame.
- Update the test code to assign the return value to a variable and print out its contents by calling the
str()function.
Before we write code to fix up the file, it is a good idea to print out what is in the file. The next few tasks are designed to get you in the habit of printing information out. We can't write the fix-up code without knowing what we are fixing. :)
df <- fixMixed_v1() print( str( df ) )
It should show Apple as a numeric column.
- This function is specific to a particular data file and it will achieve a particular goal, namely ensuring the Apple column is numeric. It is good practice to use a function name that indicates the function's purpose (which we do here - sort of - we specify that the file is mixed and that we are fixing it up, but not what or how we are fixing it up - also we indicate that it is the first version of the function with v1). It is also good practice to write a comment at the beginning of each function, indicating what it does and what it returns. Add this comment before writing any code:
- Write a second function, fixMixed_v2 that will use an alternate approach to fixing the Apple column and which will make the Banana column contain strings.
- Add comments to reflect this purpose:
# Read in mixed.csv and change the Apple column to be all numeric. # Also change the Banana column to be a character vector. # Return the dataframe with the adjusted data.
- Read in the data using read.csv, assigning the data frame to a variable. This time use the na.strings parameter and give it the value
c("NA", "."). - Print the result of calling the
str()on the data frame to note the difference. - Add code to call fixMixed_v2 to the bottom of the file and Source it to test it.
-
Convert the "Banana" column to a character vector using
as.character(). - On the last line, return the data frame
- Update the test code to assign the return value to
a variable and print out its contents by calling the
str()function.
df <- fixMixed_v2() print( summary( df ) )
- Add comments to reflect this purpose:
- Practice logical indexing with two helpful functions: The which function lets you select data based on a test. The seq function lets you create sequences of numbers with different patterns.
- Create a function called learnWhich to encapsulate code that uses the
whichfunction. The function should have one parameter, which is the data fram to use.Add a comment indicating the purpose of this function is to give you practice with which and that the dataframe parameter is expected to have the fixed up data from mixed.csv in it.
The
which()function takes in a logical vector and returns the set of indices corresonding to the TRUE elements of the vector. An expression like myDataFrame$Apple < 5 generates a logical vector. See what happens when you pass it to which().which(myDataFrame$Apple < 5)
Use the
whichfunction to assign to the variable indexes the set of indices of the values of the Pear column that are less than 50. Print out the indexes variable and double-check that it is correct. To double-check it, print out the Pear column and use indexes to select that subset of the data (e.g. myDataFrame$Pear[indexes]. All of the values should be less than 50.Update your test code to call this function, and Source it to test it. Note (you many want to comment out any print functions in fixMixed_v2 so that your Console is not cluttered.)
df <- fixMixed_v2() learnWhich( df )
- Create a function called learnSeq to encapsulate code that uses the
whichfunction. The function should have one parameter, which is the data fram to use.Add a comment indicating the purpose of this function is to give you pract ice with which and that the dataframe parameter is expected to have the fixed up data from mixed .csv in it.
The
seq()function takes in one, two, or three arguments and allows you to generate sequences of numbers. The three argument version takes in the starting value, the ending value, and the step value. Use the seq() function to assign to the variable indexes2 the values from 1 to 10 in steps of 3. Use indexes2 to print out that subset of the Pear column. You should get the values at position 1, 4, 7, and 10.Add test code to the bottom of the file and Source it to test it now, and after each new line of code is added.
Print out the values in the Apple column at odd indices (i.e. 1, 3, etc.) using seq to generate the indexes.
Print out the values between 4.5 and 5.5 in the Apple column using whatever method you like.
- Create a function called learnWhich to encapsulate code that uses the
-
Explore adding arrows, text, and lines to a plot.
There are many other capabilities built into the R base plotting system. One of these is the ability to put lines, text, and arrows into a plot.
Create a function called decorateSizePlot to ecapsulate this task. The function should have one parameter, which is the data frame to use. This function does not need to return anything explicitly. Be sure to test it as you add features to the plot (add code to the bottom following the pattern of previous tasks).
- Write a comment at the beginning of the function indicating that this function makes a barlplot from the Size column of the data frame and annotates it with an arrow and text.
- Make a bar plot using the Size column (don't forget to use the
tablefunction). Adjust the amount of space between the columns and specify the x-axis label and main title. - Use the
arrows()function to add an arrow to the plot pointing at the small bar. - Use the
text()function to add some text at the tail of the arrow saying "There are lots of small fruits". - Use the
lines()function to add a blue line of width 2 underneath the text.
-
Generating random numbers from uniform or normal distributions can be extremely useful for a wide variety of applications. For this task, you will create random numbers and view their distributions using a histogram.
Create a function called plotRandomDistributions to encapsulate this task. The function should have one optional parameter, N, which is the number of points to use. Give the N parameter a default value of 1000. Inside the function, write code to do the following tasks. This function does not need to return anything explicitly. As with the previous tasks, test as you go.
- Assign to the variable flat the result of using the
runif()function to generate a vector of N uniformly distributed numbers in the range 0 to 100. - Assign to the variable bump the result of using the
rnorm()function to genreate a vector of N normally distributed numbers with a mean of 50 and a standard deviation of 10. - Generate a histogram plot of the uniformly distributed numbers. Use the argument
xaxt='n'to tell the hist() function not to generate an X-axis. Then use theaxis()function to create a new X-axis. - Generate a histogram plot of the normally distributed numbers. As with the prior step, create your own X-axis with customized features like a smaller font size (e.g. cex.axis parameter).
Once you have completed and tested the plotRandomDistributions function, at the end of your R file call it 3 times: once with the argument 100, once with no argument, and once with the argument 10000. Save one of the plots of the normal distribution and hand it in with your code.
- Assign to the variable flat the result of using the
Part 0: Setup
Get ready to write some R code and write a function to read data.
Open R Studio or a text editor and Create a new R file called project4.R. Put your name, Project 4, and the date at the top of the file. Save your file to an appropriate working directory.
Part 1: Fixing up Data
Part 2: Exploring which and seq
Part 3: Adding Decorations to Plots
Part 4: Exploring Random Numbers
Explore generating different kinds of random numbers.
Report
Answer the following questions. Submit your answers as a plain text file or PDF in your handin directory. Put your name at the top of the file. No credit will be given for any other format or for a file without a name.
- What does it mean to make a function argument optional?
- What is the value of organizing your code using functions?
- Why is it important to understand the types of your data?
Handin
Create a project4 folder inside the Private folder in your Courses directory. Put your project4.R file and your text/PDF file with your answers into the project4 folder. They should be the only documents in the project4 folder. You do not need to put a copy of the GSS data in your handin folder.
Fall 2020