R: Shouldn't generic methods work internally within a package without it being attached?
Asked Answered
P

1

0

I am writing a package that uses classes and functions from the spatial sp library. sp exports methods for rbind (am I correct in calling rbind a generic?).

For instance, the following code creates two SpatialPoints objects and then uses rbind.SpatialPoints to join them together:

> crdsA <- matrix(c(1,2,3,4), ncol = 2)
> crdsB <- matrix(c(7,8), ncol = 2)
> 
> sptsA <- sp::SpatialPoints(crdsA)
> sptsB <- sp::SpatialPoints(crdsB) 
> 
> sp::rbind.SpatialPoints(sptsA, sptsB)
SpatialPoints:
     coords.x1 coords.x2
[1,]         1         3
[2,]         2         4
[3,]         7         8
Coordinate Reference System (CRS) arguments: NA 

However, if I then convert the SpatialPoints to SpatialPointsDataFrame (a higher level object class within the sp library), and then use rbind.SpatialPointsDataFrame, I get an error:

> sptsdfA <- sp::SpatialPointsDataFrame(sptsA, data.frame(IDs = c(1,2)))
> sptsdfB <- sp::SpatialPointsDataFrame(sptsB, data.frame(IDs = 3))
> 
> sp::rbind.SpatialPointsDataFrame(sptsdfA, sptsdfB)
Error in rbind2(..1, r) : 
  no method for coercing this S4 class to a vector

A look at the rbind.SpatialPointsDataFrame source code reveals that it calls rbind for SpatialPoints:

rbind.SpatialPointsDataFrame <- function(...) {
    dots = list(...)
    names(dots) <- NULL # bugfix Clement Calenge 100417
    sp = do.call(rbind, lapply(dots, function(x) as(x, "SpatialPoints")))
    df = do.call(rbind, lapply(dots, function(x) x@data))
    SpatialPointsDataFrame(sp, df, coords.nrs = dots[[1]]@coords.nrs)
}

So this seems to be the problem, but I do not understand why. If I attach the sp library, then none of these problems occur, but I thought that since rbind was being called internally within rbind.SpatialPointsDataFrame, then the rest of the library did not to be attached.

Within the context of the package I am creating, even if I include import(sp) and importFrom(sp,rbind.SpatialPoints) in the NAMESPACE, the code above does not work.

I guess there is clearly something I am not understanding with regards to loading, attaching and importing packages. Could anyone explain why sp::rbind.SpatialPointsDataFrame does not work without the rest of the library being attached, and how I can get it to work within my package?

Thanks a lot!

Pris answered 18/12, 2016 at 21:47 Comment(0)
R
0

rbind is not a usual generic: since its signature has ... as its first (and only) argument, it cannot dispatch on the first argument. It has been problementic in all cases to program methods for it. Have you looked at maptools::spRbind?

Rider answered 19/12, 2016 at 7:16 Comment(1)
Thanks. I have indeed used maptools::spRbind as a temporary (or maybe permanent?) solution. I read up on method dispatch here, and so that makes a bit of sense... although I don't quite understand how this relates to the package being attached or not?Pris

© 2022 - 2024 — McMap. All rights reserved.