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"
Thanks!
first: Return First or Last n Elements of A Data Object.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With