[r] Determine path of the executing script

I have a script called foo.R that includes another script other.R, which is in the same directory:

#!/usr/bin/env Rscript
message("Hello")
source("other.R")

But I want R to find that other.R no matter what the current working directory.

In other words, foo.R needs to know its own path. How can I do that?

This question is related to r file path rscript r-faq

The answer is


See findSourceTraceback() of the R.utils package, which

Finds all 'srcfile' objects generated by source() in all call frames. This makes it possible to find out which files are currently scripted by source().


I work in an HPC cluster environment. I develop my code in a different location from where I do my production runs. During development, I'm usually calling R interactively from the command line (not using RStudio). There is lots of source("foo.R") going on.

During production runs, I usually write a bash script that tries different parameters and runs each set of parameters in a separate directory. The bash script utilizes the workload manager (i.e. SLURM). In this environment, it is trivial to set an environmental variable. With this in mind, the below solution works best for me.

other.R

my_message <- function(){
return("R is awkward")
}

foo.R

srcpath = Sys.getenv("R_SRC")
# Check if runnning w/o setting R_SRC - presumably done in directory of development, i.e. /path/to/R/code
if(srcpath == ""){
    srcpath="./"
}
source(sprintf("%s/other.R", srcpath))
string = my_message()
print(string)

If running this from the R interactive shell and within /path/to/R/code, simply do

> source("foo.R")

If running not from the interactive shell and not running from /path/to/R/code, set the environmental variable R_SRC first, then call Rscript

$ export R_SRC=/path/to/R/code/
$ Rscript /path/to/R/code/foo.R

frame_files <- lapply(sys.frames(), function(x) x$ofile)
frame_files <- Filter(Negate(is.null), frame_files)
PATH <- dirname(frame_files[[length(frame_files)]])

Don't ask me how it works though, because I've forgotten :/


This works for me. Just greps it out of the command line arguments, strips off the unwanted text, does a dirname and finally gets the full path from that:

args <- commandArgs(trailingOnly = F)  
scriptPath <- normalizePath(dirname(sub("^--file=", "", args[grep("^--file=", args)])))

I like this approach:

this.file <- sys.frame(tail(grep('source',sys.calls()),n=1))$ofile
this.dir <- dirname(this.file)

I've made a package for this as of 2020-12-03 available on CRAN called "this.path".

Install it using:

install.packages("this.path")

and then use it by:

this.path::this.path()

or

library(this.path)

this.path()

I still have my original answer below, though it is less functional than the version in the package. On a Unix-alike OS, strange characters (such as " ") in the 'Rscript' command-line argument 'file' are replaced (such as "~+~"). R does this so that it is easier to use that filename for other system commands, but this isn't what we want. Given that we want a path usable in R, any such strange character sequences must be replaced.

Original Answer:

My answer is an improvement upon Jerry T's answer. The issue I found is that he is guessing whether a source call was made by checking if variable ofile is found in the first frame on the stack. This will not work with nested source calls, nor source calls made from a non-global environment. Additionally, a source call must be looked for before checking the command-line arguments, that has also been fixed. Here is my solution:

this.path <- function (verbose = getOption("verbose"))
{
    where <- function(x) if (verbose)
        cat("Source: ", x, "\n", sep = "")


    # loop through functions that lead here from most recent to earliest looking
    #     for an appropriate source call (a call to function base::source or base::sys.source)
    # an appropriate source call is a source call in which
    #     argument 'file' has been evaluated (forced)
    # this means, for example, the following is an inappropriate source call:
    #     source(this.path())
    # the argument 'file' is stored as a promise
    #     containing the expression "this.path()"
    # when the value of 'file' is requested, it assigns the value
    #     returned by evaluating "this.path()" to variable 'file'
    # there are two functions on the calling stack at
    #     this point being 'source' and 'this.path'
    # clearly, you don't want to request the 'file' argument from that source
    #     call because the value of 'file' is under evaluation right now!
    # the trick is to ask if variable ('ofile' for base::source, 'exprs' for base::sys.source)
    #     exists in that function's evaluation environment. this is because that
    #     variable is created AFTER argument 'file' has been forced
    # if that variable does exist, then argument 'file' has been forced and the
    #     source call is deemed appropriate. For base::source, the filename we want
    #     is the variable 'ofile' from that function's evaluation environment. For
    #     base::sys.source, the filename we want is the variable 'file' from that
    #     function's evaluation environment.
    # if that variable does NOT exist, then argument 'file' hasn't been forced and
    #     the source call is deemed inappropriate. The 'for' loop moves to the next
    #     function up the calling stack (if available)
    #
    # unfortunately, there is no way to check the argument 'fileName' has been forced
    #     for 'debugSource' since all the work is done internally in C. Instead,
    #     we have to use a 'tryCatch' statement. When we ask for an object by name
    #     using 'get', R is capable of realizing if a variable is asking for its
    #     own definition (a recursive definition). The exact error is "promise already
    #     under evaluation" which indicates that the promise evaluation is requesting
    #     its own value. So we use the 'tryCatch' to get the argument 'fileName'
    #     from the evaluation environment of 'debugSource', and if it does not raise
    #     an error, then we are safe to return that value. If not, the condition
    #     returns false and the 'for' loop moves to the next function up the calling
    #     stack (if available)


    if (.Platform$GUI == "RStudio")
        dbs <- get("debugSource", mode = "function", "tools:rstudio",
            inherits = FALSE)
    for (n in seq.int(sys.nframe(), 1L)[-1L]) {
        if (identical(sys.function(n), base::source) &&
            exists("ofile", envir = sys.frame(n), inherits = FALSE)) {
            path <- get("ofile", envir = sys.frame(n), inherits = FALSE)
            if (!is.character(path))
                path <- summary.connection(path)$description
            where("call to function source")
            return(normalizePath(path, mustWork = TRUE))
        }
        else if (identical(sys.function(n), base::sys.source) &&
            exists("exprs", envir = sys.frame(n), inherits = FALSE)) {
            path <- get("file", envir = sys.frame(n), inherits = FALSE)
            where("call to function sys.source")
            return(normalizePath(path, mustWork = TRUE))
        }
        else if (.Platform$GUI == "RStudio" && identical(sys.function(n), dbs) &&
            tryCatch({
                path <- get("fileName", envir = sys.frame(n), inherits = FALSE)
                TRUE
            }, error = function(c) {
                FALSE
            })) {
            where("call to function debugSource in RStudio")
            return(normalizePath(path, mustWork = TRUE))
        }
    }


    # if the for loop is passed, no appropriate
    #     source call was found up the calling stack
    # next, check if the user is running R from the command-line
    #     on a Windows OS, the GUI is "RTerm"
    #     on a Unix    OS, the GUI is "X11"


    if (.Platform$OS.type == "windows" && .Platform$GUI == "RTerm" ||  # running from Windows command-line
        .Platform$OS.type == "unix" && .Platform$GUI == "X11") {       # running from Unix command-line


        # get all command-line arguments that start with "--file="
        # check the number of command-line arguments starting with "--file="
        #     in case more or less than one were supplied


        path <- grep("^--file=", commandArgs(), value = TRUE)
        if (length(path) == 1L) {
            path <- sub("^--file=", "", path)
            where("Command-line argument 'file'")
            return(normalizePath(path, mustWork = TRUE))
        }
        else if (length(path)) {
            stop("'this.path' used in an inappropriate fashion\n",
                "* no appropriate source call was found up the calling stack\n",
                "* R is being run from the command-line and formal argument \"--file=\" matched by multiple actual arguments\n")
        }
        else stop("'this.path' used in an inappropriate fashion\n",
            "* no appropriate source call was found up the calling stack\n",
            "* R is being run from the command-line and argument \"--file=\" is missing\n")
    }
    else if (.Platform$GUI == "RStudio") {  # running R from 'RStudio'


        # function ".rs.api.getActiveDocumentContext" from the environment "tools:rstudio"
        #     returns a list of information about the document where your cursor is located
        #
        # function ".rs.api.getSourceEditorContext" from the environment "tools:rstudio"
        #     returns a list of information about the document open in the current tab
        #
        # element 'id' is a character string, an identification for the document
        # element 'path' is a character string, the path of the document


        adc <- get(".rs.api.getActiveDocumentContext",
            mode = "function", "tools:rstudio", inherits = FALSE)()
        if (adc$id != "#console") {
            path <- adc$path
            if (nzchar(path)) {
                where("active document in RStudio")
                return(normalizePath(path, mustWork = TRUE))
            }
            else stop("'this.path' used in an inappropriate fashion\n",
                "* no appropriate source call was found up the calling stack\n",
                "* active document in RStudio does not exist\n")
        }


        sec <- get(".rs.api.getSourceEditorContext", mode = "function",
            "tools:rstudio", inherits = FALSE)()
        if (!is.null(sec)) {
            path <- sec$path
            if (nzchar(path)) {
                where("source document in RStudio")
                return(normalizePath(path, mustWork = TRUE))
            }
            else stop("'this.path' used in an inappropriate fashion\n",
                "* no appropriate source call was found up the calling stack\n",
                "* source document in RStudio does not exist\n")
        }
        else stop("'this.path' used in an inappropriate fashion\n",
            "* no appropriate source call was found up the calling stack\n",
            "* R is being run from RStudio with no documents open\n")
    }
    else if (.Platform$OS.type == "windows" && .Platform$GUI == "Rgui") {  # running R from 'RGui' on Windows


        # on a Windows OS only, the function "getWindowsHandles" from the base
        # package "utils" returns a list of external pointers containing the windows
        # handles. The thing of interest are the names of this list, these should
        # be the names of the windows belonging to the current R process. Since
        # RGui can have files besides R scripts open (such as images), a regular
        # expression is used to subset only windows handles with names that exactly
        # match the string "R Console" or end with " - R Editor". I highly suggest
        # that you NEVER end a document's filename with " - R Editor". From there,
        # similar checks are done as in the above section for 'RStudio'


        wh <- names(utils::getWindowsHandles(pattern = "^R Console$| - R Editor$",
            minimized = TRUE))


        if (!length(wh))
            stop("this error SHOULD be unreachable, as far as I know it's impossible to have an R\n",
                "  process running without the R Console open. If you reached this error, please\n",
                "  send a bug report to the package maintainer")


        path <- wh[1L]
        if (path != "R Console") {
            path <- sub(" - R Editor$", "", path)
            if (path != "Untitled") {
                where("active document in RGui")
                return(normalizePath(path, mustWork = TRUE))
            }
            else stop("'this.path' used in an inappropriate fashion\n",
                "* no appropriate source call was found up the calling stack\n",
                "* active document in RGui does not exist\n")
        }


        path <- wh[2L]
        if (!is.na(path)) {
            path <- sub(" - R Editor$", "", path)
            if (path != "Untitled") {
                where("source document in RGui")
                return(normalizePath(path, mustWork = TRUE))
            }
            else stop("'this.path' used in an inappropriate fashion\n",
                "* no appropriate source call was found up the calling stack\n",
                "* source document in RGui does not exist\n")
        }
        else stop("'this.path' used in an inappropriate fashion\n",
            "* no appropriate source call was found up the calling stack\n",
            "* R is being run from RGui with no documents open\n")
    }
    else if (.Platform$OS.type == "unix" && .Platform$GUI == "AQUA") {  # running R from 'RGui' on Unix
        stop("'this.path' used in an inappropriate fashion\n",
            "* no appropriate source call was found up the calling stack\n",
            "* R is being run from AQUA which requires a source call on the calling stack\n")
    }
    else stop("'this.path' used in an inappropriate fashion\n",
        "* no appropriate source call was found up the calling stack\n",
        "* R is being run in an unrecognized manner\n")
}

I liked steamer25's solution as it seems the most robust for my purposes. However, when debugging in RStudio (in windows), the path would not get set properly. The reason being that if a breakpoint is set in RStudio, sourcing the file uses an alternate "debug source" command which sets the script path a little differently. Here is the final version which I am currently using which accounts for this alternate behavior within RStudio when debugging:

# @return full path to this script
get_script_path <- function() {
    cmdArgs = commandArgs(trailingOnly = FALSE)
    needle = "--file="
    match = grep(needle, cmdArgs)
    if (length(match) > 0) {
        # Rscript
        return(normalizePath(sub(needle, "", cmdArgs[match])))
    } else {
        ls_vars = ls(sys.frames()[[1]])
        if ("fileName" %in% ls_vars) {
            # Source'd via RStudio
            return(normalizePath(sys.frames()[[1]]$fileName)) 
        } else {
            # Source'd via R console
            return(normalizePath(sys.frames()[[1]]$ofile))
        }
    }
}

I had issues with the implementations above as my script is operated from a symlinked directory, or at least that's why I think the above solutions didn't work for me. Along the lines of @ennuikiller's answer, I wrapped my Rscript in bash. I set the path variable using pwd -P, which resolves symlinked directory structures. Then pass the path into the Rscript.

Bash.sh

#!/bin/bash

# set path variable
path=`pwd -P`

#Run Rscript with path argument
Rscript foo.R $path

foo.R

args <- commandArgs(trailingOnly=TRUE)
setwd(args[1])
source(other.R)

By looking at the call stack we can get the filepath of each script being executed, the two most useful will probably either be the currently executing script, or the first script to be sourced (entry).

script.dir.executing = (function() return( if(length(sys.parents())==1) getwd() else dirname( Filter(is.character,lapply(rev(sys.frames()),function(x) x$ofile))[[1]] ) ))()

script.dir.entry = (function() return( if(length(sys.parents())==1) getwd() else dirname(sys.frame(1)$ofile) ))()

I have wrapped up and extended the answers to this question into a new function thisfile() in rprojroot. Also works for knitting with knitr.


I couldn't get Suppressingfire's solution to work when 'source'ing from the R console.
I couldn't get hadley's solution to work when using Rscript.

Best of both worlds?

thisFile <- function() {
        cmdArgs <- commandArgs(trailingOnly = FALSE)
        needle <- "--file="
        match <- grep(needle, cmdArgs)
        if (length(match) > 0) {
                # Rscript
                return(normalizePath(sub(needle, "", cmdArgs[match])))
        } else {
                # 'source'd via R console
                return(normalizePath(sys.frames()[[1]]$ofile))
        }
}

The answer of rakensi from Getting path of an R script is the most correct and really brilliant IMHO. Yet, it's still a hack incorporating a dummy function. I'm quoting it here, in order to have it easier found by others.

sourceDir <- getSrcDirectory(function(dummy) {dummy})

This gives the directory of the file where the statement was placed (where the dummy function is defined). It can then be used to set the working direcory and use relative paths e.g.

setwd(sourceDir)
source("other.R")

or to create absolute paths

 source(paste(sourceDir, "/other.R", sep=""))

A slimmed down variant of Supressingfire's answer:

source_local <- function(fname){
    argv <- commandArgs(trailingOnly = FALSE)
    base_dir <- dirname(substring(argv[grep("--file=", argv)], 8))
    source(paste(base_dir, fname, sep="/"))
}

Note that the getopt package provides the get_Rscript_filename function, which just uses the same solution presented here, but is already written for you in a standard R module, so you don't have to copy and paste the "get script path" function into every script you write.


Steamer25's approach works, but only if there is no whitespace in the path. On macOS at least the cmdArgs[match] returns something like /base/some~+~dir~+~with~+~whitespace/ for /base/some\ dir\ with\ whitespace/.

I worked around this by replacing the "~+~" with a simple whitespace before returning it.

thisFile <- function() {
  cmdArgs <- commandArgs(trailingOnly = FALSE)
  needle <- "--file="
  match <- grep(needle, cmdArgs)
  if (length(match) > 0) {
    # Rscript
    path <- cmdArgs[match]
    path <- gsub("\\~\\+\\~", " ", path)
    return(normalizePath(sub(needle, "", path)))
  } else {
    # 'source'd via R console
    return(normalizePath(sys.frames()[[1]]$ofile))
  }
}

Obviously you can still extend the else block like aprstar did.


#!/usr/bin/env Rscript
print("Hello")

# sad workaround but works :(
programDir <- dirname(sys.frame(1)$ofile)
source(paste(programDir,"other.R",sep='/'))
source(paste(programDir,"other-than-other.R",sep='/'))

I just worked this out myself. To ensure portability of your script always begin it with:

wd <- setwd(".")
setwd(wd)

It works because "." translates like the Unix command $PWD. Assigning this string to a character object allows you to then insert that character object into setwd() and Presto your code will always run with its current directory as the working directory, no matter whose machine it is on or where in the file structure it is located. (Extra bonus: The wd object can be used with file.path() (ie. file.path(wd, "output_directory") to allow for the creation of a standard output directory regardless of the file path leading to your named directory. This does require you to make the new directory before referencing it this way but that, too, can be aided with the wd object.

Alternately, the following code performs the exact same thing:

wd <- getwd()
setwd(wd)

or, if you don't need the file path in an object you can simply:

setwd(".")

Here there is a simple solution for the problem. This command:

script.dir <- dirname(sys.frame(1)$ofile)

returns the path of the current script file. It works after the script was saved.


I tried almost everything from this question, Getting path of an R script, Get the path of current script, Find location of current .R file and R command for setting working directory to source file location in Rstudio, but at the end found myself manually browsing the CRAN table and found

scriptName library

which provides current_filename() function, which returns proper full path of the script when sourcing in RStudio and also when invoking via R or RScript executable.


I also had this problem, and none of the above solutions worked for me. Maybe with the source or things like that, but it was not clear enough.

I found this, for me elegant, solution:

paste0(gsub("\\", "/", fileSnapshot()$path, fixed=TRUE),"/")

The important thing in that is the fileSnapshot() that gives you a lot of information about a file. It returns a list of 8 elements. When you pick path as the list element, the path is returned with \\ as separator, so the rest of the code is just to change that.

I hope this helps.


Amazing there is no '$0' type structure in R! You can do it with a system() call to a bash script written in R:

write.table(c("readlink -e $0"), file="scriptpath.sh",col=F, row=F, quote=F)
thisscript <- system("sh scriptpath.sh", intern = TRUE)

Then just split out the scriptpath.sh name for other.R

splitstr <- rev(strsplit(thisscript, "\\/")[[1]])
otherscript <- paste0(paste(rev(splitstr[2:length(splitstr)]),collapse="/"),"/other.R")

If rather than the script, foo.R, knowing its path location, if you can change your code to always reference all source'd paths from a common root then these may be a great help:

Given

  • /app/deeply/nested/foo.R
  • /app/other.R

This will work

#!/usr/bin/env Rscript
library(here)
source(here("other.R"))

See https://rprojroot.r-lib.org/ for how to define project roots.


99% of the cases you might simply use:

sys.calls()[[1]] [[2]]

It will not work for crazy calls where the script is not the first argument, i.e., source(some args, file="myscript"). Use @hadley's in these fancy cases.


You can wrap the r script in a bash script and retrieve the script's path as a bash variable like so:

#!/bin/bash
     # [environment variables can be set here]
     path_to_script=$(dirname $0)

     R --slave<<EOF
        source("$path_to_script/other.R")

     EOF

My all in one! (--01/09/2019 updated to deal with RStudio Console)

#' current script file (in full path)
#' @description current script file (in full path)
#' @examples
#' works with Rscript, source() or in RStudio Run selection, RStudio Console
#' @export
ez.csf <- function() {
    # http://stackoverflow.com/a/32016824/2292993
    cmdArgs = commandArgs(trailingOnly = FALSE)
    needle = "--file="
    match = grep(needle, cmdArgs)
    if (length(match) > 0) {
        # Rscript via command line
        return(normalizePath(sub(needle, "", cmdArgs[match])))
    } else {
        ls_vars = ls(sys.frames()[[1]])
        if ("fileName" %in% ls_vars) {
            # Source'd via RStudio
            return(normalizePath(sys.frames()[[1]]$fileName))
        } else {
            if (!is.null(sys.frames()[[1]]$ofile)) {
            # Source'd via R console
            return(normalizePath(sys.frames()[[1]]$ofile))
            } else {
                # RStudio Run Selection
                # http://stackoverflow.com/a/35842176/2292993
                pth = rstudioapi::getActiveDocumentContext()$path
                if (pth!='') {
                    return(normalizePath(pth))
                } else {
                    # RStudio Console
                    tryCatch({
                            pth = rstudioapi::getSourceEditorContext()$path
                            pth = normalizePath(pth)
                        }, error = function(e) {
                            # normalizePath('') issues warning/error
                            pth = ''
                        }
                    )
                    return(pth)
                }
            }
        }
    }
}

I would use a variant of @steamer25 's approach. The point is that I prefer to obtain the last sourced script even when my session was started through Rscript. The following snippet, when included on a file, will provided a variable thisScript containing the normalized path of the script. I confess the (ab)use of source'ing, so sometimes I invoke Rscript and the script provided in the --file argument sources another script that sources another one... Someday I will invest in making my messy code turns into a package.

thisScript <- (function() {
  lastScriptSourced <- tail(unlist(lapply(sys.frames(), function(env) env$ofile)), 1)

  if (is.null(lastScriptSourced)) {
    # No script sourced, checking invocation through Rscript
    cmdArgs <- commandArgs(trailingOnly = FALSE)
    needle <- "--file="
    match <- grep(needle, cmdArgs)
    if (length(match) > 0) {
      return(normalizePath(sub(needle, "", cmdArgs[match]), winslash=.Platform$file.sep, mustWork=TRUE))
    }
  } else {
    # 'source'd via R console
    return(normalizePath(lastScriptSourced, winslash=.Platform$file.sep, mustWork=TRUE))
  }
})()

You can use the commandArgs function to get all the options that were passed by Rscript to the actual R interpreter and search them for --file=. If your script was launched from the path or if it was launched with a full path, the script.name below will start with a '/'. Otherwise, it must be relative to the cwd and you can concat the two paths to get the full path.

Edit: it sounds like you'd only need the script.name above and to strip off the final component of the path. I've removed the unneeded cwd() sample and cleaned up the main script and posted my other.R. Just save off this script and the other.R script into the same directory, chmod +x them, and run the main script.

main.R:

#!/usr/bin/env Rscript
initial.options <- commandArgs(trailingOnly = FALSE)
file.arg.name <- "--file="
script.name <- sub(file.arg.name, "", initial.options[grep(file.arg.name, initial.options)])
script.basename <- dirname(script.name)
other.name <- file.path(script.basename, "other.R")
print(paste("Sourcing",other.name,"from",script.name))
source(other.name)

other.R:

print("hello")

output:

burner@firefighter:~$ main.R
[1] "Sourcing /home/burner/bin/other.R from /home/burner/bin/main.R"
[1] "hello"
burner@firefighter:~$ bin/main.R
[1] "Sourcing bin/other.R from bin/main.R"
[1] "hello"
burner@firefighter:~$ cd bin
burner@firefighter:~/bin$ main.R
[1] "Sourcing ./other.R from ./main.R"
[1] "hello"

This is what I believe dehmann is looking for.


This works for me

library(rstudioapi)    
rstudioapi::getActiveDocumentContext()$path

Examples related to r

How to get AIC from Conway–Maxwell-Poisson regression via COM-poisson package in R? R : how to simply repeat a command? session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium How to show code but hide output in RMarkdown? remove kernel on jupyter notebook Function to calculate R2 (R-squared) in R Center Plot title in ggplot2 R ggplot2: stat_count() must not be used with a y aesthetic error in Bar graph R multiple conditions in if statement What does "The following object is masked from 'package:xxx'" mean?

Examples related to file

Gradle - Move a folder from ABC to XYZ Difference between opening a file in binary vs text Angular: How to download a file from HttpClient? Python error message io.UnsupportedOperation: not readable java.io.FileNotFoundException: class path resource cannot be opened because it does not exist Writing JSON object to a JSON file with fs.writeFileSync How to read/write files in .Net Core? How to write to a CSV line by line? Writing a dictionary to a text file? What are the pros and cons of parquet format compared to other formats?

Examples related to path

Get Path from another app (WhatsApp) How to serve up images in Angular2? How to create multiple output paths in Webpack config Setting the correct PATH for Eclipse How to change the Jupyter start-up folder Setting up enviromental variables in Windows 10 to use java and javac How do I edit $PATH (.bash_profile) on OSX? Can't find SDK folder inside Android studio path, and SDK manager not opening Get the directory from a file path in java (android) Graphviz's executables are not found (Python 3.4)

Examples related to rscript

Passing command line arguments to R CMD BATCH Determine path of the executing script

Examples related to r-faq

What does "The following object is masked from 'package:xxx'" mean? What does "Error: object '<myvariable>' not found" mean? How do I deal with special characters like \^$.?*|+()[{ in my regex? What does %>% function mean in R? How to plot a function curve in R Use dynamic variable names in `dplyr` Error: unexpected symbol/input/string constant/numeric constant/SPECIAL in my code How should I deal with "package 'xxx' is not available (for R version x.y.z)" warning? How to select the row with the maximum value in each group R data formats: RData, Rda, Rds etc