3

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

Community
  • 1
  • 1
Alex
  • 15,186
  • 15
  • 73
  • 127
  • `source()` is designed to execute all the commands in a file. Both of those commands in your example are assigning a result to a variable. They aren't really that different. What about `x<-function(a) function(x) x+1; b<-x(5); b(4)`. Both of those "create functions." Would you want to run them both? – MrFlick Oct 28 '14 at 23:36
  • @RichardScriven, the linked answer would help if I were able to find the lines containing `function(...){`, and pair it with the closing `}`. – Alex Oct 28 '14 at 23:38
  • @MrFlick, I only want to assign variables where these variables are functions. I could rephrase my question to say that I only want to execute all commands that are related to defining functions. – Alex Oct 28 '14 at 23:39
  • @Alex R is not strongly typed. A variable can be anything and may change at any time. You need to run and execute the code to see what it is at any given moment. – MrFlick Oct 28 '14 at 23:40
  • @RichardScriven, yes definitely, as I can then supply the required arguments to `source2` in the linked answer. – Alex Oct 28 '14 at 23:41
  • @MrFlick I don't understand what you mean by the last comment. Are you saying that R does not understand what things will assign variables of type function until the code is run? – Alex Oct 28 '14 at 23:42
  • @Alex. Correct. For example: `f<-if(runif(1)<.5) {function(x) x+1} else {4}` Is `f` a function or a numeric value? – MrFlick Oct 28 '14 at 23:44
  • @MrFlick I see what you mean now, but luckily I do not wish to run that example you supplied. (My code has no examples like that). – Alex Oct 28 '14 at 23:47
  • Thanks @RichardScriven, that at first glance seems to give the right line number pairs. – Alex Oct 28 '14 at 23:49
  • Perhaps the question earlier today the led to a link to a description of lazy loading could be of use? Load the index into an environment and process from there? – IRTFM Oct 28 '14 at 23:59
  • @BondedDust which question is this? – Alex Oct 29 '14 at 00:16
  • what happened to @RichardScriven's answers and comments? – Alex Oct 29 '14 at 01:40
  • http://stackoverflow.com/questions/26616958/list-of-variables-from-r-workspace-file – IRTFM Oct 29 '14 at 01:50
  • 2
    @RichardScriven, why did you delete your answer ... ? – Ben Bolker Oct 26 '15 at 02:55

2 Answers2

7

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()))
}
Adam Hoelscher
  • 1,804
  • 2
  • 17
  • 33
0

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.

caesar0301
  • 1,913
  • 2
  • 22
  • 24