13.2 Write and document functions - Video Tutorials & Practice Problems
Video duration:
7m
Play a video:
Video transcript
<v Voiceover>Now it's time</v> to start writing functions to be included in the package. So first we make a new file with control + shift + N. So we want to save this file. It goes in the R folder, because it's going to be R code. You can see there already is a file in here that came as an example. We're going to ignore that, and we'll call this one multiplication.r. Now all these code files have to have an appropriate extension, the most common of which is a lowercase r. Uppercase r works as well but the lowercase is where everyone is moving to. So as our example we'll just create a very simple function called simple.ex. It will be a function which takes two arguments x and y, and simply multiplies them together and returns the result. This is absolutely something that could have been done using base r but it's something we just want to use as an example. So we will save this. Theoretically you are done right now. You wrote a function. You could go ahead and build this package. The problem is though, you haven't documented this function. If you want to use this function at home just for yourself or amongst your friends you're fine. You don't need any documentation. However, if you want to be able to put this on CRAN you need to make a help file. Help files can get kind of complex. If you recall, we'll do a quick search for mean, they look like this when the finished product is done. So we'll go look at the example that was generated already. Which is in man and under simple package. And we can see it's all this latex light code. It's very laborious writing this and it's a bit of a pain. Fortunately there is something called roxygen2 which lets you write the documentation right with the function and automatically generate those documentation files. So let's look at what's needed. You need a title, and notice our studio starts filling it in automatically for you, it's amazing. So the title of this function is simple.ex. You want a description of the file. The description is that it's a simple example. And you want more details of the file. Details is a little more of a (mumbles). This is a simple example of a function. And you can see here the title goes right here Arithmetic Mean. The description is here, and the details comes down here towards the bottom. This example doesn't have one, but it would be beneath the return value. Further arguments you can give it an alias. This helps when you do question mark the name of the function. You can have multiple functions all point to the same help file. In this case we will just do simple.ex. You want to give the author credit where it's due. And if you want this to be seen by your end users you have to say export then the name of the function. That's the basics, but we're still not done. You now need to define the arguments and what it returns. So we say at param, the name of the argument, and then a describe it. You say a numeric vector. You need another param for y. You say a numeric vector. Then you need to explain what it returns, and this could be short or detailed. So we will say, x times y, that that's what it is returning. Then lastly, you should put in examples. Such as simple.ex of five times three. Or simple.ex of one through three times four through six. Now the trick is these examples need to work to get it on CRAN. Because when you build the package it checks to make sure the examples work. And if they don't work, your package can't be submitted. There are a number of other tags, and we'll learn about a few more of them, but these are the basics, the minimum of what you need. So now that we have this built we need to generate that documentation file. So we come down to the console and we do require devtools. And now we can just run the document function. Proper thing is you need to make sure roxygen2 is installed. Because even though you have devtools installed, that doesn't mean you necessarily have roxygen2 installed. They're not dependencies of each other. So go ahead and install that. Make sure you grab roxygen2 and not just roxygen. Major changes were made and they abandoned roxygen and made roxygen2. Sort of like how ggplot became ggplot2. So now let's require devtools again, and let's even require roxygen2 to be safe. And now we will document our package. So look what it just did. It updated the documentation and it updated the namespace. Let's go look at what we created. We now have simpleexe.rd, which is the help file all taken care of for us. We also have an updated namespace. Here we see we are exporting simple.ex and that is it. But now let's say you want to build another function that depends on another package. For instance let's say we even keep this function but we want it to depend on plyr for some reason. We can come up here and say at import plyar. And what this will do is, if we save it and then document, it will go to the namespace and import the plyr function. What we then have to do is go to the description and add another field here. We have to come here and tell the package that it is importing plyr. So we say imports plyr. You can import as many packages as you would like, it's just a comma separated list. Now there's often some confusion. Let's say we come back to multiplication, and we also import ggplot2. Let's say we do that and we run the documentation again. The namespace is updated so now we import ggplot2 as well. And the description file got changed so we reload that. And it actually took away our imports tag here. We never saved it we should have saved it. So we'll go back to say imports plyr. Now we have an option. We could use imports or depends, and there's a big difference. So they both mean your package relies on these packages, and when your package gets installed from CRAN these both will be installed as well. The difference is, is that when you load your package by saying requires simple or library simple, ggplot2 will be loaded and everything inside ggplot2 will be usable. However plyr will not be loaded. Your package will still be able to access all of the plyr functions, but the end user won't be unless they explicitly require plyr as well. That's a very important distinction to remember. To keep things clean you should put as many packages as possible in imports and only keep things you absolutely need loaded in depends. So it's important to remember when building your package, build your functions, make them do what you want, and it can be something as simple as multiplying two vectors or it could be something really complex. When you build your function document it using roxygen2. Then you give it a title, description, details. All these fields here. Make sure you have it properly taken care of and then before you're ready to build document it by running the document function. After that you'll be ready to go and you can check and build your package.