Make a user-created function in R - r

I'm sorry if this has been asked before but I can't find the answer.
Let's say I write a small function in R
add2<-function(a){
return(a+2)
}
I save it as add2.R in my home directory (or any directory). How do I get R to find it??
> add2(4)
Error: could not find function "add2"
I know I can open up the script, copy/paste it in the console, run it, and then it works. But how do I get it built-in so if I open and close R, it still runs without me copying and pasting it in?

One lightweight option:
dump("add2", file="myFunction.R")
## Then in a subsequent R session
source("myFunction.R")
An alternative:
save("add2", file="myFunction.Rdata")
## Then just double click on "myFunction.Rdata" to open
## an R session with add2() already in it
## You can also import the function to any other R session with
load("myFunction.Rdata")
Until you're ready to package up functions into your own private package, storing them in well organized, source()-ready text files (as in the 1st example above) is probably the best strategy. See this highly up-voted SO question for some examples of how experienced useRs put this approach into practice.

Before invoking the function (e.g. at the beginning of the script), you should source the file containing your user defined function/s, i.e. :
source("add2.R") # this executes add2.R script loading add2 function
Basically, source function executes the code included in the script passed as argument. So if the file contains only functions definitions it loads the function in memory for future use.

If you want to start it automatically, then you have to set-up startup script and then use one of the methods outlined in answers above.
/Library/Frameworks/R.framework/Versions/2.15/Resources/etc/
is(for mac) the location of Rprofile.site, which must be edited adequately.
My version of it is:
.First <- function()
{
dir='~/Desktop/Infobase/R/0_init/0_init.R'
if(file.exists(dir))
{
source(dir, chdir = TRUE)
} else {cat("startup file is not found at:",dir)}
cat("\nWelcome at", date(), "\n")
}
.Last <- function()
{
cat("\nGoodbye at ", date(), "\n")
}
Note, that after you have sourced 1 R script, you do not need to enter this file anymore. Just do all you need from the file you sourced. In my case file "0_init.R" contains no functions, it just contains loading of other scripts. Well, you've got the idea.
Also, if you are doing this I recommend you to store them in new environment. Actual environments are not really suitable for your own functions(They are better implemented if you have a package developed, otherwise you lose a lot of control).
use "attach", "detach", "search", etc....
attach(FUN,name="af2tr")

Related

safe way of including a function in R environment

I have wrote a bunch of functions for my project for users to invoke interactively.
Now I'd like to have them safely included in the session.
I want to avoid a scenario where user types rm(list=ls()) and erases my functions from memory.
Initially I tried to save function to another environment and attach that environment to search path but along the way I changed something and R is not longer able to find my function.
My code is split among multiple files but snippet below ilustrates how are things organised, normally user will run app.R because it contains refernces to other files, configurations etc.:
./funs.R
id.mapping.env <- new.env(parent = emptyenv())
attach(id.mapping.env)
id.mapping.env$test_function<- function() {
print("It works")
}
./app.R
source("./funs.R")
test_function
If I run app.R I get error:
Error: could not find function "test_function"
Why won't R find my function? Do I have to resort to writing my own package to ensure all of my functions can be found?
I am not familiar with writing packages, if this is needed could you give me a tiny demo/tutorial(which I am googling right now).

how to make a function available at start up in R

I have a user defined function in R
blah=function(a,b){
something with a and b
}
is it possile to put this somewhere so that I do not need to remember to load in the workspace every time I start up R? Similar to a built in function like
summary(); t.test(); max(); sd()
You can put the function into your .rprofile file.
However, be very careful with what you put there, since it essentially makes your code non-reproducible — it now depends on your .rprofile:
Let’s say you have an R code file performing some analysis, and the code uses the function blah. Executing the code on any other system will fail due to the non-existence of the blah function.
As a consequence, this file should only contain system-specific setup. Don’t define helper functions in there — or if you do, make them defined only in interactive sessions, so that you have a clear environment when R is running a non-interactive script:
if (interactive()) {
# Helper functions go here.
}
And if you find yourself using the same helper functions over and over again, bundle them into packages (or modules) and reuse those.

How to call a function in another file without actually run codes other than that function in that file? [duplicate]

I would like source() to only find and load functions within a .R file.
For example, in the file Analysis.R:
print.hw <- function() {
print("hello world")
}
x <- 1 + 2
...
When I source("Analysis.R"), it will create the function print.hw but also assign x, which I do not want.
Anyone have any ideas? The best I could find was this question:
Source only part of a file
This works without using regex. It's also probably less computationally efficient than regex solutions. It creates a new environment, sources the entire file, then returns only the functions back to the global environment.
SourceFunctions<-function(file) {
MyEnv<-new.env()
source(file=file,local=MyEnv)
list2env(Filter(f=is.function,x=as.list(MyEnv)),
envir=parent.env(environment()))
}
I think its a good practice to separate test code before the end of source files (as we usually do in Python) and then invoke them with external scripts or packages (like testthat). Hadley's dplyr may give you a reference.

Only source functions in a .R file

I would like source() to only find and load functions within a .R file.
For example, in the file Analysis.R:
print.hw <- function() {
print("hello world")
}
x <- 1 + 2
...
When I source("Analysis.R"), it will create the function print.hw but also assign x, which I do not want.
Anyone have any ideas? The best I could find was this question:
Source only part of a file
This works without using regex. It's also probably less computationally efficient than regex solutions. It creates a new environment, sources the entire file, then returns only the functions back to the global environment.
SourceFunctions<-function(file) {
MyEnv<-new.env()
source(file=file,local=MyEnv)
list2env(Filter(f=is.function,x=as.list(MyEnv)),
envir=parent.env(environment()))
}
I think its a good practice to separate test code before the end of source files (as we usually do in Python) and then invoke them with external scripts or packages (like testthat). Hadley's dplyr may give you a reference.

Quit and restart a clean R session from within R?

Is there a way I can make an alias, within R, that will execute q() and then restart a clean R session?
And yes, I am too lazy to type q() and then the letter R :)
If you're in RStudio:
command/ctrl + shift + F10
You can also use
.rs.restartR()
Depending on how you start R try placing one of these lines into your .Rprofile file:
makeActiveBinding("refresh", function() { shell("Rgui"); q("no") }, .GlobalEnv)
makeActiveBinding("refresh", function() { system("R"); q("no") }, .GlobalEnv)
Then entering this into the R console:
refresh
will shut down the current session and start up a new one.
I found that .rs.restartR() works similar to pressing ctrl+shift+F10. but dose not unload the packages
As another alternative, Emacs ESS (>= 16.10) can reload the inferior R process via inferior-ess-r-reload-hook which is bound to C-c C-e C-r by default.
After looking for a solution to this, I solved my problem based on this solution here, using the R Package RDCOMClient.
The solution bellow just work within RStudio (Windows), once it simulates the keypresses ctrl+ shift + F10.
The RDCOMClient package must be installed with the command bellow:
install.packages("RDCOMClient", repos = "http://www.omegahat.net/R")
The code to simulate the keypresses within RStudio (Windows 10) are:
library(RDCOMClient)
wsh <- COMCreate("Wscript.Shell")
wsh$SendKeys("^+{F10}")
In the last line in the code above, the 'ctrl' key is represented by '^' and the shift key by '+'. All the explanations for this key representaions are available here.
Just after running the last line of the code above, the whole R session in RStudio will be reset, according to #steadyfish's comment. That is, it removes all the data from current session and unload all the loaded packages in the session.
Old post, but none of the answers quite work (for me, I'm using Windows, haven't tested others), so I'll add my solution. Some of my terminology might be off here, but this should get the point across:
Above answers don't quite work
Most of the answers submitted here involve using shell or system which doesn't quite work because while they open a new R console and do instruct the original console to close, the new console is a process running in the application context of the old console. That means the original console cannot close until the new console closes. Some of the users above such as hedgedandlevered reported that closing the original console forces the new console to close. When I try, the new console does open, but the old console remains open in a frozen state until the new console is closed.
The basic problem is calling shell or system does not change the application context from the original console to the new one, and therefore the original process cannot terminate until the new console closes.
Alternative that works for me
Instead use shell.exec which would normally be used to open a file in the default application based on file type. When used on a .exe, apparently, it runs the executable. The important difference, though, is that the system starts the application in it's own separate context. So here's the code that works for me:
makeActiveBinding("restart.R", function() { shell.exec(paste0(R.home(),"/bin/x64/Rgui.exe")); q("no") }, .GlobalEnv)
You'll need to edit the file path /bin/x64/Rgui.exe to match whatever you use to start R. You just put this line in your .Rprofile file, then you can call it by entering restart.R in your R code.
The downside of this over other methods is that you can't pass command line arguments like --no-save as you would with just shell, but at least this will let you close out the original R process.
Write this function in your .Rprofile
r <- function() {
assign('.Last', function() {system('R')}, envir = globalenv())
quit(save = 'no')
}
r() restarts you R session. Loaded packages will not reload. Your environment wont be saved.
Works for Linux. No idea of what may happen on other OS
In line with Martin Morgan's idea of using .Last(); this restarts R with the same set of command-line options as previously called:
restart_r <- function(status = 0, debug = TRUE) {
if (debug) message("restart_r(): Customizing .Last() to relaunch R ...")
assign(".Last", function() {
args <- commandArgs()
system2(args[1], args = args[-1])
}, envir = globalenv())
if (debug) message("restart_r(): Quitting current R session and starting a new one ...")
quit(save = "no", status = status, runLast = TRUE)
}
I needed the same refresh session functionality on windows and I ended up with a slightly modified version of the code:
makeActiveBinding("refresh", function() { shell(paste0("start \"\" \"", R.home(), "/bin/x64/Rgui.exe\"")); q("no") }, .GlobalEnv)
On windows you need to modify the Rprofile.site file. It is under R's etc directory. Also watch out for the last part of the path the bin/x64 can change according to your system configuration. I hope this will help others too.
I think, one realizes the best use of R by setting a current working directory in options. Then whenever your workspace /session file starts showing you up or has enough of your work in it (in between projects) you can just rename this default session file in the working directory after closing R and R/Rstudio will automatically start you in a new workspace/session file, without disturbing your current work.
Remember to quit R and rename the current session file
Of course if you do not want to save the current work you have to make sure you reset objects or operations on them were done after copying from original objects so they are as is. Trust me, knowing you can always load the old workspaces is a temptation but is more useful than not.
In short quit R, it gives you some gap while quitting means this workspace is full, rename it after completing the quit and restart R/Rstudio with a fresh workspace. You can always load select objects in the new workspace. Ideally all important work should be in Project directories but you still need a history of your jobs to go back to at times and saved sessions come in useful at some point once you are on longer projects. If you don't need any of it just rm(list=ls())
Also, I like the RDComClient idea by #Eduardo Alvin but it has been discontinued.
ALTERNATIVE OPTION
A simple alternative to get rid of the baggage at any time inside your workspace is to use save.image
save.image("Rstreamingscience.data")
quit(save='no')
load("Rstreamingscience.data") ##G:/ADA registers##
save.image("Rstreamingscience.data")
This leaves you free to come and go as you please and open as many workspaces as you need.
makeActiveBinding("refresh", function() { system(paste0(R.home(),"/bin/i386/R")); q("no") }, .GlobalEnv)
or with --save or --no-save
paste0(R.home(),"/bin/i386/R --no-save")
I think this is what you need if you've used setwd() before calling refresh (although neither this nor the original version works for me, since it restarts R then closes itself, a new window is never opened. If anyone can comment on this, please do so)
I have written the following function.
Remember! You can only use it once, then you have to reload it after the R session restarts.
clc <- function() {
rm(list = ls(envir = globalenv()),envir = globalenv()) #clear Vars from global enviroment
gc() #grabage colector
cat("\014") #clc
.rs.restartR() #clear session
}
Sometimes detaching a package also helps.

Resources