edzer / sp

Classes and methods for spatial data

Home Page:http://edzer.github.io/sp/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`slot<-`() on a SpatialPointsDataFrame object inside a function produces a side effect

choisy opened this issue · comments

Using the `slot<-`() function on a SpatialPointsDataFrame object inside a function produces a side effect as illustrated in the example below. Let's consider the following object generated in the ASDAR book:

url <- "https://github.com/r-spatial/asdar-book.org/blob/master/docs/datasets/CRAN051001a.txt"
CRAN_df <- read.table(url, header = TRUE)
CRAN_mat <- cbind(CRAN_df$long, CRAN_df$lat)
llCRS <- CRS("+proj=longlat +ellps=WGS84")
CRAN_spdf1 <- SpatialPointsDataFrame(CRAN_mat, CRAN_df, proj4string = llCRS, match.ID = TRUE)

Now, let's consider the following function that changes the data slot of a SpatialPointsDataFrame object as so:

change_data <- function(spdf) {
  `slot<-`(spdf, "data", value = data.frame(index = seq_along(spdf)))
  spdf
} 

Let's now run this function on CRAN_spdf1:

change_data(CRAN_spdf1)

We can see that it does the job. The problem is that it has a side effect and also changes the inputed data:

CRAN_spdf1

This is an interesting phenomenon but completely unrelated to sp.
The same thing happens with an arbitrary S4 class:

foo <- setClass("foo", slots = c(x = "numeric"))
obj <- foo(x = 1)

setx_slot <- function (object)
{
    slot(object, "x") <- NA_real_
    object
}

setx_slot(obj)@x
#> [1] NA
obj@x
#> [1] 1

setx_slot_bad <- function (object)
{
    "slot<-"(object, "x", value = NA_real_)
}

setx_slot_bad(obj)@x
#> [1] NA
obj@x
#> [1] NA

The standard form slot() <- rather than "slot<-"() needs to be used to edit a copy of the object as usually done in R. I'm actually not sure if this pass-by-reference behaviour of "slot<-"() is intended.

This issue can be closed.

Thanks for sorting this out, @bastistician !