Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.First function in R

Tags:

r

I don't understand the point of .First function in R. My reason is any code in .Rprofile will be sourced and executed when R starts up anyway.

this

.First<-function(){                                                                 
    library('devtools')                                     
}

and this

library('devtools')

in .Rprofile have exactly the same effect.

However, here is an example that shows .First can make a difference:

example 1, you can see X11.options()$type correctly becomes Xlib as set in .Rprofile

>> cat .Rprofile
.First <- function() {
    library(devtools)
}

setHook(
    packageEvent("grDevices", "onLoad"),
    function(...) grDevices::X11.options(type="Xlib")
)

>> Rscript -e 'X11.options()$type'
[1] "Xlib"

example 2, you can see X11.options()$type is still cairo, the setHook in .Rprofile didn't take effect

>> cat .Rprofile
library(devtools)

setHook(
    packageEvent("grDevices", "onLoad"),
    function(...) grDevices::X11.options(type="Xlib")
)

>> Rscript -e 'X11.options()$type'
[1] "cairo"
  • in what case do I absolutely have to use .First function?
  • why .First made a difference in the example above?

Thanks!

like image 649
Jim Green Avatar asked Feb 12 '16 06:02

Jim Green


People also ask

What does First () do in R?

first: Return First or Last n Elements of A Data Object.

How do I extract the first element of a vector in R?

To get the first element of a vector, we could do the following. In R, array indexes start at 1 - the 1st element is at index 1. This is different than 0-based languages like C, Python, or Java where the first element is at index 0. Notice that for the second example, we put a function inside the square brackets.


2 Answers

It may be unnecessary but it does provide yet another place to modify the startup. It certainly doesn't hurt having it.

I generally run R in different directories to keep things separated; link to a common .Rprofile; and use .First to tailor the current R run environment to the specific problem I'm working on. If .First action wasn't available I'd have to create one.

like image 187
DAV Avatar answered Oct 11 '22 23:10

DAV


One benefit of putting startup code in .First() instead of .RProfile is that you can use local variables which won't stay in your Global environment after .First() completes.

For example, my .First() displays the list of .R files on the project directory in as many columns as will fit:

localFiles <- list.files(pattern = "\\.R$", ignore.case = TRUE)
maxChars <- max(nchar(localFiles))
numCols <- as.integer((options("width")$width-2) / (1 + maxChars))  # how many columns will fit?
fmt <- sprint(" %%-%d", maxChars)                  # left justified in each column
for (nn in localFiles) {
  if ((match(nn, localFiles) %% numCols) == 1) cat(" ")   # indent each row
  cat(sprint(fmt, nn))
  if ((match(nn, localFiles) %% numCols) == 0) cat("\n")  # end of row
}
if (length(localFiles) %% numCols != 0) cat("\n")         # end last row if not complete

Since this is in .First(), all of the temporary variables get cleaned up when the function returns and the Global environment remains clean.

like image 21
scoco Avatar answered Oct 11 '22 22:10

scoco