Reading GRASS GIS vector attribute tables into R

Linking GRASS GIS and R will give you a very powerful set of geo-spatial analytical tools. The spgrass6 offers a very convenient interface between GRASS GIS and R. You can read more about this package in Bivand, R. 2007. Using the R-GRASS interface. OSGeo Journal 1, 36-38.

Read the whole vector layer
It allows you amongst others to easily import vector data layers from GRASS GIS into R using the function readVECT6(). This will import the whole vector layer. But what if you you only need to import the attribute table? Importing the whole vector layer would give unnecessarily overhead and would take (much) longer to import.

Import the attribute table directly
As an alternative, you can directly download the attribute tables. The GRASS GIS database is a folder, which is divided in sub-folders per location which in turn are further divided in sub-folders per mapset. In these mapset folders you can find the attribute tables. If you are not familiar with the GRASS GIS database structure, check out this tutorial.

If your attribute tables are stored as dbf files (still the default in GRASS GIS 6.4), you could use the read.dbf() function to import your data. The dbf files with attribute tables are normally located in the dbf folder in the mapset that contains your vector layers.

If you use SQLite as your database backend (default in GRASS 7.0 and also recommended for GRASS 6.4), you can dbReadTable() using the RSQLite package. By default each mapset has its own SQLite database with the attribute tables of all vector layers in that mapset.

Another way to import your attribute table
Another way to do this is to run the GRASS db.select() function from within R usingĀ  execGRASS() (function in spgrass6). This will import the attribute table as a character vector, with one row per vector element; e.g. an attribute table with two rows (+ header) and 10 columns will be imported as:

[1]"cat|VALUE|X_ll|Y_ll|M1y1901|M2y1901|M3y1901|M4y1901|M5y1901|M6y1901"
[2] "1|23136|-25.25|16.75|A|400|400|413|438|488" 
[3] "2|23137|-25.25|17.25|B|400|400|413|450|500"

An elegant solution to convert this in a data.frame, from Roger Bivand in this email thread, is to use textConnection() in combination with read.table(). In the example below the attribute table TEST is imported.

  b <- execGRASS("db.select", parameters=list(table="TEST"), intern=TRUE)
  con <- textConnection(b)
  c <- read.table(con, header=TRUE, sep="|")
  close(con)

The advantage of this method is that you don’t have to locate the database that is holding your attribute table. Of course, you will have to start R from the GRASS GIS command line, so this makes especially sense if this step is part of a set of analysis that involve more writing data GRASS to/from R.

Note: You can also use v.db.select instead of db.select. This has the advantage that you are sure you are using the right attribute table (the name of the attribute table normally is, but does not have to be the same as the name of the vector layer).

  b <- execGRASS("v.db.select", parameters=list(map="TEST"), intern=TRUE)
  con <- textConnection(b)
  c <- read.table(con, header=TRUE, sep="|")
  close(con)

Comparing the time it takes to import the data
And as last point, let me demonstrate why, if you only need the attribute table, it makes sense to use the last method rather then importing the whole vector layer. The vector layer CRU is a point layer containing 11042 points:

system.time(a <- readVECT6("CRU"))
   user  system elapsed
359.554  63.671 390.978

system.time({
  b <- execGRASS("db.select", parameters=list(table="CRU"), intern=TRUE)
  con <- textConnection(b)
  c <- read.table(con, header=TRUE, sep="|")
  close(con)
})

   user  system elapsed
 14.776   8.157  18.296

I haven’t included a test with readdbf() and dbReadTable() but I expect they will take about the same time as the method with textConnection() + read.table(). All the extra time it takes readVECT6() is because it needs to read in the spatial information, which is really wasted time if you are not going to use that extra information.

About these ads

One thought on “Reading GRASS GIS vector attribute tables into R

  1. Pingback: Import GRASS function console output as data.frame in R | Ecostudies

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s