Import GRASS function console output as data.frame in R

In R you can use system calls or the spgrass6 package to run GRASS GIS functions. To do this, you need to run R from within GRASS GIS. This is as simple as starting GRASS GIS and subsequently starting R from the command line. See the GRASS-wiki for a more detailed background.

The issue at hand
One of the user-cases is when you want to (1) run a GRASS function on e.g., a raster layer and (2) capture the console output in a R data frame. For example, you can run the following in R:

MyVariables <- execGRASS("r.stats", flags="c", input="MyMap", separator=",", intern=TRUE)

However, the output is not in a very convenient format. Implementing the function above will give you the variable MyVariables :

> MyVariables
[1] "1,10523"  "*,109900"
> str(MyVariables)
 chr [1:2] "1,10523" "*,109900"

What you probably would like is a data.frame with two columns, the first containing the values before the comma (1 and *) and the second column containing the values behind the comma (10523, 109900).

How I do this
There are various ways to split the elements of the output vector MyVariables. The most elegant solution, in my opinion, is to use the textConnection() function in combination with read.table(). I have mentioned these two functions before, for the more specific case of importing a vector attribute table into R. Here I want to import the console output of the GRASS function as a data frame.

b <- execGRASS("r.stats", flags="c", input="MyMap", separator=",", intern=TRUE)
con <- textConnection(b)
MyVariables <- read.table(con, header=FALSE, sep=",")
close(con)

Note that this will only work when the original GRASS functions

  • The GRASS GIS output is in table format and written to the console
  • The rows of the output data is written as separate lines to the console
  • The columns are separated by a separator like comma or space

Wrapping it in a function
I tend to forget the details so to simplify things and to make it easier for myself to remember, I wrapped the above in a function.

get.outputGRASS <- function(x, separator=",", Header=FALSE){
    con<- textConnection(x)
    MyVar <- read.table(con, header=Header, sep=separator)
    close(con)
    return(MyVar)
}

I added this function to a text file R_startup_scripts.r that contain the functions that I want to load in R at startup. This is done by adding the following line to my .Rprofile:

.First <- function(){ 
     source("/home/paulo/Documents/R_startup_scripts.r")
}

You obviously need to adapt the path and file name if you want to do the same.

Some examples
GRASS functions for which this works are, amongst others

  • r.stats
  • r.info

I am listing these because I just used them. I will try to expand the list whenever I come across GRASS functions for which this works too.

r.stats

> b &lt;- execGRASS("r.stats", flags="c", input="MyMap", separator=",", intern=TRUE)
> get.outputGRASS(b
  V1     V2
1  1  10523
2  * 109900

> str(MyVariables)
'data.frame':	2 obs. of  2 variables:
 $ V1: Factor w/ 2 levels "*","1": 2 1
 $ V2: int  10523 109900

r.info

> b &lt;- execGRASS("r.info", flags="g", map="pnv_1@test", intern=TRUE)
> get.outputGRASS(b, separator="=")
         V1        V2
1     north    545850
2     south  -2121570
3      east   1755090
4      west   -309060
5     nsres        90
6     ewres        90
7      rows     29638
8      cols     22935
9     cells 679747530
10 datatype      CELL

Let me know if you have other / better ways to get your function outputs to/from R. And make sure to check out the GRASS-wiki which lists a number of other websites with relevant information.

Leave a comment