Header

Get GRASS function output in R

Author: Paulo van Breugel
Updated on: 2017-05-30

Getting started

In this tutorial, we'll use the North Carolina data set. If you want to run the code yourself, you first need to download the data set from the GRASS GIS sample data download page and open GRASS in the nc_spm_08_grass7 location. Next, from the command line open R (or Rstudio).

The issue

In R, you can use system calls or the rgrass7 package to run GRASS functions. Output data that is written to the console by the GRASS function can be captured and assigned to a R variable using the intern=TRUE parameter. For example, you can run the GRASS function r.stats in R as follows:

library(rgrass7)
MyVariables <- execGRASS("r.stats", flags="c",  input="landclass96@PERMANENT",
               separator=",",  intern=TRUE)

However, the output is not always directly useable in R. Running the function above will for example give you the variable MyVariables :

> MyVariables
[1] "1,427"   "3,22402" "4,60"    "5,6077"  "6,569" 

What you probably would like is a data.frame with two columns, the first containing the values before the comma (1, 2, 3, 4, 5, 6) and the second column containing the values behind the comma (427, 22402, 60, 6077, 569).

Solution

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(). This will import the output of the GRASS function as a data frame.

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

This will give you the output of the r.stats function in a data.frame. Note that this will only work for GRASS functions that write their output to the console like in the example above, i.e., the rows of the output data are written as separate lines and in each row columns are separated by a separator like comma or space.

> MyVariables
  V1    V2
1  1   427
2  3 22402
3  4    60
4  5  6077
5  6   569

Turning it into a function

To simplify things, you can wrap 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)
}

If you work a lot with GRASS functions in R, you can include this in a start-up script which you can then load in R at startup. This can be done by adding the following line to my .Rprofile file:

.First <- function(){ 
	source("path-to-script/R_startup_scripts.r")
}

Examples

GRASS functions for which this works are, amongst others r.stats and r.info, as shown in the examples below:

b <- execGRASS("r.stats", flags="c", input="landclass96@PERMANENT", 
               separator=",", intern=TRUE)
get.outputGRASS(b)

  V1    V2
1  1   427
2  3 22402
3  4    60
4  5  6077
5  6   569
b <- execGRASS("r.info", flags="g", map="landclass96@PERMANENT", intern=TRUE)
get.outputGRASS(b, separator="=")

         V1        V2
1     north 228527.25
2     south 215018.25
3      east    644971
4      west    629980
5     nsres      28.5
6     ewres      28.5
7      rows       474
8      cols       526
9     cells    249324
10 datatype      CELL
11    ncats         7