Producing a PDF from a single R function - r

Imagine, you define an R function to share with a pal, only a single function. In case of, you decide later to include this function in a package, you document it using Roxygen comments and tags (e. g. #' #name my_function). Is it possible to produce a PDF from this single R file? If yes, how?

1) We will use the file lc.R as an example which we first download from github. First use kitten to create the boilerplate for a package. Copy lc.R to it. Then run document from devtools to roxygenize it and finally use Rd2pdf to create the pdf, lc.pdf .
library(devtools)
library(pkgKitten)
library(roxygen2)
# set up lc in lc.R to use as a test example
u <- "https://raw.githubusercontent.com/mailund/lc/master/R/lc.R"
download.file(u, "./lc.R")
# create package containing lc.R - ignore any NAMESPACE warnings
kitten("lc")
file.copy("lc.R", "./lc/R")
# roxygenize it generating an Rd file
document("lc")
file.copy("lc/man/lc.Rd", ".")
# convert Rd file to pdf
R <- file.path(R.home("bin"), "R")
cmd <- paste(R, "CMD Rd2pdf lc.Rd")
system(cmd, wait = FALSE)
2) There used to be a package on CRAN named document (or see gitlab) which does the same thing in one step but it was removed last year. Note that the document package depends on the fritools (or see gitlab) package which was also removed. The source of both are archived on CRAN and on gitlab and it may be possible to build them yourself.
3) This approach does not create a PDF but it does allow one to view formatted help for a script converting it from the roxygen2 markup to HTML showing it in the browser. Note that the box package should not be attached, i.e. do not use a library(box) statement. Assume that lc.R is in the current directory -- see the download.file statement in (1) above. The code below may generate warnings or errors but it still works to bring up the help for the lc function in lc.R showing it in the default browser.
box::use(./lc)
box::help(lc$lc)

Related

Encoding problem when your package contains functions with non-english characters

I am building my own package, and I keep running into encoding issues because the functions in my package has non-english (non-ASCII) characters.
Inherently, Korean characters are a part of many of the functions in my package. A sample function:
library(rvest)
sampleprob <- function(url) {
# sample url: "http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20200330003851"
result <- grepl("연결재무제표 주석", html_text(read_html(url)))
return(result)
}
However, when installing the package I run into encoding problems.
I created a sample package (https://github.com/hyk0127/KorEncod/) with just one function (what is shown above) and uploaded it onto my github page for a reproducible example. I run the following code to install:
library(devtools)
install_github("hyk0127/KorEncod")
Below is the error message that I see
Error : (converted from warning) unable to re-encode 'hello.R' line 7
ERROR: unable to collate and parse R files for package 'KorEncod'
* removing 'C:/Users/myname/Documents/R/win-library/3.6/KorEncod'
* restoring previous 'C:/Users/myname/Documents/R/win-library/3.6/KorEncod'
Error: Failed to install 'KorEncod' from GitHub:
(converted from warning) installation of package ‘C:/Users/myname/AppData/Local/Temp/RtmpmS5ZOe/file48c02d205c44/KorEncod_0.1.0.tar.gz’ had non-zero exit status
The error message about line 7 refers to the Korean characters in the function.
It is possible to locally install the package with tar.gz file, but then the function does not run as intended, because the Korean characters are recognized in broken encoding.
This cannot be the first time that someone has tried building a package that has non-english (or non-ASCII) characters, and yet I couldn't find a solution to this. Any help will be deeply appreciated.
A few pieces of info that I think are related:
Currently the DESCRIPTION file specifies "Encoding: UTF-8".
I have used sys.setlocale to set the locale into Korean and back to no avail.
I have specified #encoding UTF-8 to the function to no avail as well.
I am currently using Windows where the administrative language is set to English. I have tried using a different laptop with Windows & administrative language set to Korean, and the same problem appears.
The key trick is replacing the non-ASCII characters with their unicode codes - the \uxxxx encoding.
These can be generated via stringi::stri_escape_unicode() function.
Note that since it will be necessary to completely get rid of the Korean characters in your code in order to pass the R CMD check it will be necessary to perform a manual copy & re-encode via {stringi} on the command line & paste back operation on all your R scripts included in the package.
I am not aware of an available automated solution for this problem.
In the specific use case of the example provided the unicode would read like this:
sampleprob <- function(url) {
# stringi::stri_escape_unicode("연결재무제표 주석") to get the \uxxxx codes
result <- grepl("\uc5f0\uacb0\uc7ac\ubb34\uc81c\ud45c \uc8fc\uc11d",
rvest::html_text(xml2::read_html(url)))
return(result)
}
sampleprob("http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20200330003851")
[1] TRUE
This will be a hassle, but it seems to be the only way to make your code platform neutral (which is a key CRAN requirement, and thus subject to R CMD check).
Adding for the future value (for those facing similar problems), you can also solve this problem by saving the non-ASCII characters in a data file, then loading the value & using it.
So save the character as a data file (using standard package folder names and roxygen2 package)
# In your package, save as a separate file within .\data-raw
kor_chrs <- list(sampleprob = "연결재무제표 주석")
usethis::use_data(kor_chrs)
Then in your functions load the data and use them.
# This is your R file for the function within ./R folder
#' #importFrom rvest html_text
#' #importFrom xml2 read_html
#' #export
sampleprob <- function(url) {
# sample url: "http://dart.fss.or.kr/dsaf001/main.do?rcpNo=20200330003851"
result <- grepl(kor_chrs$sampleprob[1], html_text(read_html(url)))
return(result)
}
This, yes, is still a workaround, but it runs in Windows machines without any troubles.

Using an R Markdown Document as a source for functions

I'm looking into R Markdown for documenting functions I regularly use. I will put them into an R Markdown file to document them and then be able to read my thinking behind the function if i come back to it months later
My question is, if i start a new R project, Is it possible to source the r markdown file and use the library of functions i have created just by calling them similarly to if i was sourcing a regular R file. I dont really wish to maintain two sets of function files
I appreciate this may be a beginners question but any help pointing to tutorials and the like would be greatly appreciated
Thanks
As was mentioned in the comments, you should probably create a package for this purpose. But if you insist on putting function definitions in scripts and document them using RMarkdown files, using read_chunk() from the knitr package might be the way to go.
Note that this approach differs slightly from what you requested. You wanted to have the function definition in the markdown file together with the documentation. And then you wanted to somehow source that file into your R script in order to use the function. I did not find a way to do this (even though it might be possible).
The alternative that I propose puts the function definition in its own R script, say fun.R. The Rmarkdown file then reads the function definition from fun.R and adds documentation. If you want to use the function in some other script, you can simply source fun.R (and not the markdown file). This still means that you have to maintain the code for the function definition only once.
So let me show this with an example. This is fun.R:
## ---- fun
fun <- function(x) x^2
The first line is an identifier that will be used later. The markdown file is as follows:
---
title: "Documentation of fun()"
output: html_document
---
This documents the function `fun()` defined in `fun.R`.
```{r,cache = FALSE}
knitr::read_chunk("fun.R")
```
This is the function definition
```{r fun}
```
This is an example of how to use `fun()`:
```{r use_fun}
fun(3)
```
The first chunk reads in fun.R using knitr::read_chunk. Later on, you can define an empty chunk that has the identifier that was used in fun.R as its name. This will act as if the contents of fun.R were written directly in this file. As you see, you can also use fun() in later chunks. This is a screenshot of the resulting html file:
In a script where you want to use fun() you simply add source("fun.R") to source the function definition.
You could also have several functions in a single R file and still document them separately. Simply put an identifier starting with ## ---- before each function definition and then create empty chunks referring to each one of the identifiers.
This is admittedly somewhat more complicated than what you asked for, because it involves two files instead of just one. But at least there is no redundancy
The klmr/modules package has been superseded by the box package by the same author. It is on CRAN. After the cat command below run these lines to display the roxygen2 help for add2.
box::use(./test)
box::help(test$add2)
Perhaps this is close enough -- you can use the github klmr/modules package (not the CRAN modules package) to combine roxygen2 documentation and code in a single file without creating a package. For example, after installing the modules package copy this to the clipboard and then paste it into the R console to create a single file module with embedded documentation. The subsequent code then imports it, runs a function from it and invokes help. See the documentation of the modules package for more info.
Note that this has the following advantages: (1) everything is in a single file, (2) if you later decide to move to using packages you can use the very same file in your package with roxygen2 -- no need to revise anything, (3) any learning of roxygen2 applies to packages too.
# create a file with our documentation and code
Lines <- "
#' Add two numbers.
#'
#' #param x the first number.
#' #param y the second number.
#' #return The sum.
#' #note This is just a simple example.
#'
#' This function is a simple example intended to show how to use the modules
#' package with roxygen2.
add2 <- function(x, y) x + y
"
cat(Lines, file = "test.R")
# now we can import it
# devtools::install_github("klmr/modules")
library(modules)
test <- import("test") # do not include the .R extension
test$add2(1, 2)
## [1] 3
# this will cause help page to appear
?test$add2

How to access/open arbitrary formatted (.pdf etc) documents from R's console?

http://cran.r-project.org/doc/manuals/r-release/R-exts.html#Writing-package-vignettes states:
"...In addition to the help files in Rd format, R packages allow the inclusion of documents in arbitrary other formats. The standard location for these is subdirectory inst/doc of a source package, the contents will be copied to subdirectory doc when the package is installed. Pointers from package help indices to the installed documents are automatically created. Documents in inst/doc can be in arbitrary format, however we strongly recommend providing them in PDF format, so users on almost all platforms can easily read them..."
I used roxygen package. It produced .Rd files for me. I produced .pdf of my package via " R CMD Rd2pdf causfinder/" from Windows command line ( or, via during build/install process via "roxygenize("causfinder"); build("causfinder"); install("causfinder")".)
I wanted to add some supplementary .pdf help files (that I created outside of R; from Word via save as .pdf etc.) to my package other than the one that is produced via above techniques. These supplementary .pdf files include the detailed mathematical theory and lots of samples of the functions of my package which illustrate the usage of the functions via various plots, graphs, etc. I called it TheoryOfcausfinder.pdf.
I wanted to add this supplementary .pdf file to my package. As is directed from R's above manual, I put TheoryOfcausfinder.pdf to inst\doc folder in my R's working directory. Upon build/install process, I obtained causfinder/doc/index.html and causfinder/doc/TheoryOfcausfinder.pdf in my R's library location.
The content of index.html:
"...Vignettes from package 'causfinder': The package contains no vignette meta-information.
Other files in the doc directory: TheoryOfcausfinder.pdf..."
I want the future users of causfinder to easily access/open this supplementary TheoryOfcausfinder.pdf. (I will add that there is such a file in functions' help documents)
Is there a way to open/access TheoryOfcausfinder.pdf in R's library location from (within) R's console?
(Important: By the way, since I am novice of Sweave and knitr, I do not wanna enter that path! I look for a solution outside Sweave and knitr.)
Any help will be greatly appreciated.
I don't know if you have found another solution or not yet, but I am posting some possible ideas below.
source http://www.r-bloggers.com/show-me-the-pdf-already/
# under Unix types
pdf <- getOption("pdfviewer", default='')
f <- system.file("doc", "TheoryOfcausfinder.pdf", package = "causfinder")
system2(pdf, args = f)
source http://www.r-bloggers.com/show-me-the-pdf-already/
# under MS Windows
f <- system.file("doc", "TheoryOfcausfinder.pdf", package = "causfinder")
shell.exec(normalizePath(f))
source Opening PDF within R studio using file.show studio-using-file-show/33791818
# under OS X
f <- system.file("doc", "TheoryOfcausfinder.pdf", package = "causfinder")
system2('open', args = f, wait = FALSE)

Access function from current package when using R CMD check with vignette

I'm putting together a package; for simplicity with one function and one vignette illustrating its use.
I was able to run R CMD check packagename with no difficulties before I tried adding the vignette.
The package has a functionfoo.R in the R directory of packagename (it makes a plot with base graphics).
The vignette, in the vignettes directory, (an .Rnw file) calls function foo like this:
<<fig1, fig=true, echo=true, include=true>>=
df0 <- data.frame(x1=rnorm(10))
foo(df0)
#
I'm tying to play 'by the rules' but running R CMD check packagename as usual gives:
When sourcing 'foo.R':
Error: could not find function "foo"
Execution halted
I've tried adding the following to the .Rnw file, which didn't help:
\begin{document}
\VignetteDepends{packagename}
I've also tried this with no success:
<<fig1, fig=true, echo=true, include=true>>=
df0 <- data.frame(x1=rnorm(10))
source("foo.R")
foo(df0)
#
Note that the NAMESPACE file already contains the following:
export(foo)
Questions:
Do I need to add a specific source() command in the .Rnw file every time I call a function from the package? If so, how do I specify the path (i.e. where is R CMD check starting from when checking the vignette?)
Or should I take the easy way out by adding the following to the DESCRIPTION file:
BuildVignettes: False
(As I'm able to build a .pdf from the existing .Rnw file).
I'm trying to follow the advice in Writing R extensions.
Your vignette needs to have library("mypkg") at the top so that your own functions, like foo, can be found. I believe this is because the vignette building runs in a clean environment so it doesn't know about your package or any other for that matter unless you bring it up.
If you have such a line already, put a minimal example of your vignette into your question, and include your sessionInfo() as we may need that to figure it out.

Where is the .R script file located on the PC?

I want to find the location of the script .R files which are used for computation in R.
I know that by typing the object function, I will get the code which is running and then I can copy and edit and save it as a new script file and use that.
The reason for asking to find the foo.R file is
Curiosity
Know what is the algorithm used in the numerical computations
More immedietly, the function from stats package I am using, is running results for two of the arguments and not the others and have to figure out how to make it work.
Error shown by R implies that there might be some modification required in the script file.
I am looking for a more general answer, if its possible.
Edit: As per the comments so far, here is the code to compute spectrum of a time series using autoregressive methods. The data input is a univariate series.
x = ts(data)
spec.ar(x, method = "yule-walker") 1
spec.ar(x, method = "burg") 2
command 1 is running ok.
command 2 gives the following error.
Error in ar.burg.default(x, aic = aic, order.max = order.max, na.action = na.action, :
Burg's algorithm only implemented for univariate series
I did try specify all the arguments correctly like na.action=na.fail, order.max = NULL etc but the message is the same.
Kindly suggest possible solutions.
P.S. (This question is posted after searching the library folder where R is installed and zip files which come with packages, manuals, and opening .rdb, .rdx files)
See FAQ 7.40 How do I access the source code for a function?
In most cases, typing the name of the function will print its source
code. However, code is sometimes hidden in a namespace, or compiled.
For a complete overview on how to access source code, see Uwe Ligges
(2006), “Help Desk: Accessing the sources”, R News, 6/4, 43–45
(http://cran.r-project.org/doc/Rnews/Rnews_2006-4.pdf).
When R installs a package, it evaluates all the ".R" source files and re-saves them into a binary format for faster loading. Therefore you typically cannot easily find the source file.
As has been suggested elsewhere, you can simply type the function name and see the source code, or download the source package and find the source there.
library(plyr)
ddply # prints the source for ddply
# See the content of the R directory for plyr,
# but it's only binary files:
dir(file.path(find.package("plyr"), "R"))
# [1] "plyr" "plyr.rdb" "plyr.rdx"
# Get the source for the package:
download.packages("plyr", "~", type="source")
# ...then unpack and inspect the R directory...
.libPaths() should tell you all of your current library locations. It's possible to have more than one installation of a package if there are two libraries but only the one that is in the first library will be used. Unless you offer the code and the exact error message, it's not likely that anyone will be able to offer better advice.
I think you are asking to see what I call the source code for a function in a package. If so, the way I do it is as follows, which has worked successfully for me on the three times I have tried. I keep these instructions handy in a few places and just copied and pasted them here:
To see the source code for a function in Program R download the package containing the function. Specifically, download the file that ends in "tar.gz". This is a compressed file. Expand the compressed file using, for example, "WinZip". Now you need to open the uncompressed file that ends in ".tar". Download the free software "7-Zip". Click on the file "7zFM.exe" and navigate to the directory containing the ".tar" file. You can extract the contents of that ".tar" file into a new folder. The contents consist of R files showing the source code for the functions in the R package.
EDIT:
Today (July 8, 2012) I was able to open the 'tar.gz' file using the latest version of 'WinZIP' and could copy the contents (the source code) from there without having to use '7-Zip'.
EDIT:
Today (January 19, 2013) I viewed the source code for functions in base R by downloading the file
'R-2.15.2.tar.gz'
To download that file go to the http://cran.at.r-project.org/ webpage and click on that file in this line:
"The latest release (2012-10-26, Trick or Treat): R-2.15.2.tar.gz, read what's new in the latest version."
Unzip the file. WinZip will work, or it did for me. Then search your computer for readtable.r or another base R function.
agstudy noted here https://stackoverflow.com/questions/14417214/source-file-for-r-function that source code for read.csv is located in the file readtable.r, so do not expect every base R function to have its own file.

Resources