6

I'm pretty new to R and I'm trying to source a file which is again sourcing files. So I have a file, lets call it mother.R which contains a source call:

source ("grandmother.R")

mother.R and grandmother.R are in the same directory.

I would now like to source mother.R:

source ("C:/Users/whatever/R/mother.R", chdir=T)

My assumption was that the chdir=T would cause the source within the source to be looked for under C:/Users/whatever/R/, but it does not find grandmother.R when sourcing like this. Do I missunderstand chdir? Is there a way to do this without have to use absolute paths in mother.R?

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
chuelibrueder
  • 85
  • 1
  • 4
  • It's unclear what you actually want to do, but I believe `chdir=T` only affects the working directory while the code in `mother.R` is being run, not afterwards. But in general, there's no good reason to use `source` inside a function or script. If you can explain what your goal is, we can suggest a more efficient approach. – Carl Witthoft Oct 23 '13 at 11:25
  • 1
    @CarlWitthoft I'm surprised you say there's never a good reason to use `source`. Is there a better way to split code into multiple files? – Matthew Sep 10 '19 at 15:58
  • @Matthew Why would you split code that runs together into separate files? But maybe a better question is "what is in the OP's files to begin with?" . Normally you should build a *package* so that all desired functions are in the same Namespace. Running code off macros (scripts) is poor practice. – Carl Witthoft Sep 10 '19 at 18:50

1 Answers1

11

Your understanding of how source works seems correct to me. But let's write an example so you can compare with your setup and maybe find where you went wrong.

Let the /Users/me/test/mother.R file contain the following:

print("I am the mother")
print(paste("The current dir is:", getwd()))
source("grandmother.R") # local path

and let the /Users/me/test/grandmother.R file contain the following:

print("I am the grandmother")

Where you start will help understand:

> getwd()
[1] "/Users/me"

This does not work:

> source("/Users/me/test/mother.R")
[1] "I am the mother"
[1] "The current dir is: /Users/me"
Error in file(filename, "r", encoding = encoding) : 
  cannot open the connection
In addition: Warning message:
In file(filename, "r", encoding = encoding) :
  cannot open file 'grandmother.R': No such file or directory

because R is looking for grandmother.R in the getwd() dir...

Instead,

> source("/Users/me/test/mother.R", chdir = TRUE)
[1] "I am the mother"
[1] "The current dir is: /Users/me/test"
[1] "I am the grandmother"

works because source() temporarily changes the current directory to /Users/me/test/ where it can find grandmother.R.

When source gives you the handle back, you end up where you started, meaning the chdir is local to the source call like @CarlWitthoft pointed out.

> getwd()
[1] "/Users/me"
flodel
  • 87,577
  • 21
  • 185
  • 223
  • 3
    Thanks flodel for your help. Thanks to your simple example I found the reason it didn't work in my case. I made the mistake of using `source("grandmother.R")` inside a function in mother.R. Naturally the `chdir` does not apply if the source is not called until this funktion is called. I need to call the source outside of the definition of any functions. – chuelibrueder Oct 23 '13 at 12:25
  • 1
    It seems that it is not a great idea to source scripts in functions in general, as I just had to learn myself. – Ben Oct 22 '18 at 08:46