isciences / exactextractr

R package for fast and accurate raster zonal statistics
https://isciences.gitlab.io/exactextractr/
272 stars 26 forks source link

Incorrect detection of function signature under littler #71

Closed barryrowlingson closed 2 years ago

barryrowlingson commented 2 years ago

For some reason exact_extract doesn't correctly recognise my summary function signature when running under the littler interpreter. Here's an example that runs fine when "source"d into an R session:

library(exactextractr)
library(sf)
library(raster)

p = "POLYGON((0 0, 0.5 0.75, 1 1, 0.5 0.25, 0 0))"
p = data.frame(wkt=p)
p = st_as_sf(p, wkt="wkt")

r = raster(matrix(1:9,3,3))

f2 = function(v, f,...){return(sum(v*f))}
fdf = function(df,...){return(sum(df[,1]*df[,2]))}

s1 = exact_extract(r, p, fun=f2, summarize_df=FALSE)
message("Sum via passing both args to fun: ", s1)
s2 = exact_extract(r, p, fun=fdf, summarize_df=TRUE)
message("Sum via passing dataframe to fun: ", s1)

producing:

> source("extract.R")
Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1; sf_use_s2() is TRUE
Loading required package: sp
Sum via passing both args to fun: 11.2499997764826
Sum via passing dataframe to fun: 11.2499997764826

It also runs okay via R --vanilla < extract.R and R CMD BATCH extract.R. But with littler it doesn't correctly infer that the signature of the summary function in the second example is correct:

$ r < extract.R
Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
Loading required package: sp
Sum via passing both args to fun: 11.2499997764826
Error in .exact_extract(x, y, fun = fun, ..., include_xy = include_xy,  : 
  exact_extract was called with a function that does not appear to be of the form `function(values, coverage_fractions, ...)`

If you've not seen littler before it is a package that provides a lightweight R interpreter designed for writing command-line scripts with quick startup and slightly modified command line argument passing.

I've not looked at the source code for exact_extract to see how you do this inference so it may be due to something non-standard there or possibly something that r doesn't do for efficiency.

At some point we may want to get the littler maintainers in on this, but maybe you can figure it out...

B

dbaston commented 2 years ago

I notice that the startup message printed by sf differs between your two environments (with littler, the sf_use_s2() message is not printed.) This makes me wonder if the environment used by littler has an older version of sf, and possibly an older version of exactextractr that does not understand the summarize_df argument. Is this possible?

barryrowlingson commented 2 years ago

Yeah, weirdly r has a .libPaths() that includes a different set of paths to R. Sorry I missed that.

barryrowlingson commented 2 years ago

Further, its my configuration that has a different .libPaths() because I'd got a ~/.littler.r startup file that mucked with the default. Going to bash head against desk for a bit now. Thanks.

dbaston commented 2 years ago

Glad to see that the function signature inference is working!