17
$\begingroup$

I have been tasked with moving one of our current large stochastic models out of SAS and into a new language. Personally, I prefer a traditional compiled language, but the PI wants me to check out R, which I've never used. Our motivation for getting the model out of SAS is (1) many people don't have access to it because SAS is expensive, (2) we're looking to move away from an interpreted language, and (3) SAS is slow for the type of model we have.

For (1), obviously R satisfies the need for it to be free. For (2), ideally, we'd like to create an executable, but R is normally used as a scripted language. I see that someone has recently put out an R compiler - has this been well-received? Is it easy to use? We'd rather not force the user to download R themselves. For (3), our problem with SAS is all the time spent in I/O writing and reading data sets. Our model is computationally intensive, and we are often limited by runtime. (e.g. It's not uncommon for someone to hijack people's computers over the weekend to perform runs.) We have a similar model built in Fortran that doesn't have the same problem because all work is done in memory. How does R work? Will it be the same as SAS, in that it works in datasteps, reading and writing files? Or can it do array manipulation in memory?

$\endgroup$
2
  • $\begingroup$ You can usually speed up sas by doing all of your work in a single data step. This should reduce I/O times, as you effectively are only reading in data once. Using lots of procedures will also slow you down. For example, if you model repeatedly call proc glm or proc logistic (say for a bootstrap), it is faster to create a huge data set and use a by statement than to invoke many proc calls (say using a macro %do loop). if you program sas well, you should not be having run time problems due to reading and outputing files (at least not anymore than other software $\endgroup$ Commented Jan 22, 2012 at 14:01
  • $\begingroup$ Additionally you can use temporary arrays in sas data steps in a similar way to how you would use matrices in R. $\endgroup$ Commented Jan 22, 2012 at 14:04

6 Answers 6

19
$\begingroup$

R works in-memory - so your data do need to fit into memory for the majority of functions.

The compiler package, if I am thinking of the thing you are thinking of (Luke Tierney's compiler package supplied with R), is not the same thing as a compiled language in the traditional sense (C, Fortran). It is a byte compiler for R in the sense of Java bytecode executed by the Java VM or byte compiling of Emacs LISP code. It doesn't compile R code down into machine code but rather prepares the R code into bytecode so it can be used more efficiently than raw R code to be interpreted.

Note that if you have well formed Fortran you could probably have best of both worlds; R can call compiled Fortran routines.

$\endgroup$
4
  • $\begingroup$ Thanks! It is nice to know I could have the great R graphics and call compiled Fortran routines. This may be the answer! $\endgroup$
    – Melissa
    Commented Jan 20, 2012 at 16:49
  • 2
    $\begingroup$ Just to expand on Gavin's note about memory: see the section on Large Memory in this CRAN task view if you are working with larger data sets: cran.r-project.org/web/views/HighPerformanceComputing.html $\endgroup$ Commented Jan 20, 2012 at 23:24
  • 1
    $\begingroup$ Also think it's important to note that Rcpp could likely be used to gain incremental gains in performance. $\endgroup$ Commented Jan 20, 2012 at 23:25
  • $\begingroup$ Rcpp is useful to wrap C++ for use in/with R. It aids the process (immensely) but is still using R's basic tools to call compiled code. If the OP already has Fortran codes or Fortran skills, Rcpp may be of lesser use. $\endgroup$ Commented Jan 21, 2012 at 9:27
14
$\begingroup$

I have used SAS for 15 years, and have started using R seriously the past 6 months, with some tinkering around in it for a couple of years ahead of that. From a programming perspective, R does data manipulations directly, there is no equivalent to DATA or PROC SQLprocedures because they're not needed (the latter being more efficient in SAS when there is a lot of data manipulation to do from external data sources, e.g. administrative data). This means that, now I'm getting the hang of it, data manipulation is faster in R and requires much less code.

The main issue I have encountered is memory. Not all R packages allow WEIGHT type specifications, so if you have SAS datasets with variables used in FREQ or REPLICATE statements, you may have issues. I have looked at the ff and bigmemory packages in R but they do not appear to be compatible with all R packages, so if you have very large datasets that require analyses that are relatively uncommon, and have been aggregated, you may have issues with memory.

For automation, if you have SAS macros then you should be able to programme the equivalent in R and run as batch.

For coding in R, I was using Notepad++ and setting the language to R, and am now discovering the joys of R Studio. Both these products are free, and do language mark up like the improved SAS syntax GUI (I've only ever used the syntax screen in SAS).

There is a website, and related book, for people swapping from SAS to R. I found them useful for trying to work out how to translate some SAS commands into R.

Update: one thing that drove me nuts when coming to R is that R doesn't assume everything is a data set (data frame in R parlance), because it's not a statistical package in the way that SAS, SPSS, Stata, etc are. So, for example, it took me a while to get if statements working because I kept getting the help for if statements with vectors (or maybe matrices) whereas I needed an if statement that worked with data frames. So the help pages probably need to be read more closely than you would normally, because you'll need to check that the command you want to do will operate with the data object type you have.

The bit that still drives me crazy when learning a new R command (e.g. analysis method in a contributed package) is that the help for commands is often not entirely self-contained. I will go to the help page to try to learn the command and the usage notes often have ... contained in them. Sometimes trying to work out what can or should go where the ... is has lead me into a recursive loop. The relative brevity of the help notes, coming from SAS which provides detailed examples of syntax and worked examples with an explanation of the study in the example, was quite a large shock.

$\endgroup$
5
  • 3
    $\begingroup$ +1 Please consider updating our meta thread where we have collected links to stats software resources. There's one reply there for R and another for SAS: both would benefit from having a link to r4stats.com. (That thread is actually a part of our FAQ. We hope to keep it current and useful.) $\endgroup$
    – whuber
    Commented Jan 21, 2012 at 0:30
  • 2
    $\begingroup$ R also has packages that supports SQL access through RODBC drivers or SQLite. $\endgroup$
    – DWin
    Commented Jan 21, 2012 at 15:49
  • 1
    $\begingroup$ I agree with your comments about R help. I actually pointed out essentially what you are saying on one of the R mailing lists many years ago. The response was not positive. In fairness, I (a) probably did not express myself very well, and didn't give any concrete examples and (b) did not pursue the matter. To summarize, problem 1 is examples too complicated and involve too many unrelated concepts. Complicated examples are Ok but should follow simple examples. Problem 2 is that there is almost no annotation or explanation of what the examples do. $\endgroup$ Commented Jan 30, 2012 at 3:31
  • $\begingroup$ Regarding the R "help" reminds of something my boss said to me. "you learn R by doing it with someone who already knows R sitting next to you at the computer" $\endgroup$ Commented Feb 4, 2012 at 13:16
  • $\begingroup$ And for everyone else there are books and Stack Overflow. Yes, learning R by yourself is pretty hard, at least it has been for me. $\endgroup$
    – Michelle
    Commented Feb 4, 2012 at 17:39
10
$\begingroup$

R is a programming language. It works not in datasteps. It does whatever you want it to do, for it is but a programming language, a slave for your desires, expressed in a language of curly brackets and colons.

Think of it like Fortran or C, but with implicit vectorisation so you don't have to loop over arrays, and dynamic memory management so you don't have to malloc() or declare array sizes at any time.

It mostly does all its work in memory, but if you want to read part of a file in, mung it, then spit out some of the results, and read the next bit in, well, you go ahead and write an R program that does that.

You contradict yourself in saying the model is computationally intensive yet SAS is slow because of I/O... One or the other surely...

If you've got something similar in Fortran already, and you say you want to move away from an interpreted language, then why not just do it in Fortran as well?

The R compiler can cause some speedups, but if your R code is well written anyway you won't get anything too massive - not like writing it in C or Fortran.

$\endgroup$
1
  • $\begingroup$ Ah, I didn't explain myself well. It is intensive in its manipulation of datasets, which in SAS, means too much time spent in I/O. My initial suggestion was Fortran, but the PI is interested in us switching to R, so he wanted me to check it out. Thanks! $\endgroup$
    – Melissa
    Commented Jan 20, 2012 at 16:48
7
$\begingroup$

I understand that by default SAS can work with models that are bigger than memory, but this is not the case with R, unless you specifically use packages like biglm or ff.

However, if you are doing array work in R that can be vectorised it will be very quick - maybe half the speed of a C program in some cases, but if you are doing something that can't be vectorised, then it will seem quite slow. To give you an example:

# create a data.frame with 4 columns of standard normally distributed RVs
N <- 10000

# test 1
system.time( {df1 <- data.frame(h1=rnorm(N),
                h2=rpois(N, lambda=5),
                h3=runif(N),
                h4=rexp(N))
} )
# about 0.003 seconds elapsed time

# vectorised sum of columns 1 to 4
# i.e. it can work on an entire column all at once
# test 2
system.time( { df1$rowtotal1 <- df1$h1 + df1$h2 + df1$h3 + df1$h4 })
# about 0.001 seconds elapsed time

# test 3
# another version of the vectorised sum
system.time( { df1$rowtotal2 <- rowSums(df1[,c(1:4)]) })
# about 0.001 seconds elapsed time

# test 4
# using a loop... THIS IS *VERY* SLOW AND GENERALLY A BAD IDEA!!! :-)
system.time( {
        for(i in 1:nrow(df1)) {
                df1$rowtotal3 <- df1[i,1]+ df1[i,2] + df1[i,3] + df1[i,4]
        }
} )
# about 9.2 seconds elapsed time

When I increased N by a factor of ten to 100,000, I gave up on test 4 after 20 minutes, but tests 1:3 took 61, 3 and 37 milli-seconds each

For N=10,000,000 the time for tests 1:3 are 3.3s, 0.6s and 1.6s

Note that this was done on an i7 laptop and at 480mb for N=10million, memory was not an issue.

For users on 32-bit windows there is a 1.5gb memory limit for R no matter how much memory you have, but there is no such limit for 64-bit windows or 64-bit linux. These days memory is very cheap compared with the cost of an hour of my time so I just buy more memory rather than spend time trying to get around this. But this assumes that your model will fit in memory.

$\endgroup$
1
  • 1
    $\begingroup$ (+1) Thank you for offering the useful illustrations, Sean! $\endgroup$
    – whuber
    Commented Jan 29, 2012 at 23:23
3
$\begingroup$

(2), ideally, we'd like to create an executable, but R is normally used as a scripted language

Yes, and this is the good reason move to R. The interest of writing a R package is to allow users to easily make your functions interact with other tools provided by R, e.g. feeding them bootstraped data... or whatever they want to. If you don’t think this is important, stick to C/C++ or your favorite compiled language.

I want to add a caveat: you’re already a programmer, learning R will be easy and fast; learning efficient R programming will be longer. Because R is interpreted, the constants hidden in the $O()$ of the asymptotic complexity can be huge or small... for example, if you are interested in runs in your data, you will use rle(), it will be fast (its a precompiled function). If you script exactly the same algorithm, it will be slow (it will be interpreted). This is a basic example: you have plenty of tricks using vector and matrices, to avoid interpreted loops and make precompiled functions do all the job.

So be very careful. After your first tries, you’ll surely have a disgust with R, because you’ll find it slow, with a weird syntax, etc. Once you know it, it can be a very efficient tool. You may even end by scripting your methods in R as a preliminary phase for C/C++ coding. The ultimate stage will be to learn R’s API to create precompiled functions, and you’ll be a R wizard :)

$\endgroup$
2
$\begingroup$

Array manipulation in memory is a big thing for SAS, apparently. I do not know the specifics concerning R, but I surmise that R operates in memory by default, since the memory expanding packages for R, ff and bigmemory, move data from memory to disk. I have pointers for you if you want to improve either speed or memory usage. In order to improve speed, you first need to use R as intended, that is: vectorize your code and use byte code compilation. (Also: avoid memory-copy operations as much as possible.) Second, use the provided code profiler Rprof() to identify slow patches in your code, and rewrite them in C or C++ if need be. If you need more memory, you can use the skip argument in the read.table() function to read in your data a chunk at a time and you can also use a package such as RMySQL, which adds database manipulation utilities to R. If you need still more memory and can afford the concomitant decrease in speed, you can use the snow package to run R in parallel. (You can find details about this, and much more, in the book "The Art of R Programming", by Norman Matloff, published at the end of last year. Details about packages mentioned here can be found online.)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.