Keyword Error: calling as.geodata function in geoR with rpy2

732 Views Asked by At

I am getting SyntaxError: keyword can't be an expression in a script I am working on.

I am using rpy2 (and the R package geoR) in Python to work with a data table that is retrieved from a PostgreSQL database using R's database functions. The data is spatial data with coordinates and 2 columns of numerical data that will be used in a geostatistical model.

After the database query call, the dataframe object x looks like this:

    easting northing location attrib1 attrib2    category
1  658394.3 204987.5       p1         4.91        26.17 soil
2  658657.1 205116.7       p2         4.85        27.43 soil
...

I create an object for the geoR functions like this:

from rpy2.robjects.packages import importr geo = importr('geoR')

Calling the geoR function as

y=geo.as_geodata(x)  

works, BUT without argument data.col, it assigns the location attribute as the data attribute. (First column after coordinate attributes is default.)

Trying:

y=geo.as_geodata(x,geo.data_col="4:5")

produces:

SyntaxError: keyword can't be an expression

I can't seem to get around it. I have looked at a few posts here and looked around online, but I can't figure this one out.

2

There are 2 best solutions below

0
On

I think the error is due to you trying to pass two columns to the data_col command. Here is a working example using the meuse dataset from the gstat package.

import rpy2.robjects as robjects
from rpy2.robjects.packages import importr 
geo = importr('geoR')
gstat= importr("gstat")
robjects.r("data(meuse)")
x = robjects.r("meuse")
y = geo.as_geodata(x,data_col=5,coords_col="1:2")
vario = geo.variog(y)
robjects.r.plot(vario)

However you will notice that the above doesn't work, because geoR doesn't seem to get the coords.col or the data.col arguments. I'm not sure why this is, but a workaround to this problem is to write a wrapping function.

robjects.r('''
geodata_python <- function(obj) {
        return(as.geodata(obj, data.col=5, coords.col=1:2))
}
''')
geodata_wrapper =  robjects.globalenv['geodata_python']
y = geodata_wrapper(x)
vario = geo.variog(y)
robjects.r.plot(vario)

Using the above method you can pass additional arguments to the as.geodata function within the geodata_python function within the R environment.

HTH

1
On

Rpy2 is a bridge to Python, mapping Python types to R types whenever necessary. Here you pass a parameter of value "4:5", that is a Python str. That parameter becomes an R character (a vector of strings in the R lingo).

When you write an R function call such as foo(bar = 4:5) what you are writing is R code as the value for the parameterbar, that code will be evaluated to give the actual parameter.

I'd think that what you want is:

from rpy2.robjects.vectors import IntVector
y=geo.as_geodata(x, data_col = IntVector((4,5)))

or

base = importr('base')
y=geo.as_geodata(x, data_col = base.c(4,5))