Home > Software engineering >  Saving then loading a `tibble` causes it to be not recognised by S4 methods
Saving then loading a `tibble` causes it to be not recognised by S4 methods

Time:12-26

I have an obscure problem in R that involves the S4 class system.

First I create a tibble and save it:

df = tibble::tibble(a=1:5, b=2:6)
save(df, file="foo.Rdata")

Next, I close the R session, and start a new one (which for some reason matters).

Then, I define an S4 method that dispatches on a data.frame (which a tibble is a subclass of):

setGeneric("sumTheColumns", function(target){    
  standardGeneric("sumTheColumns")    
})    
setMethod("sumTheColumns", signature(target="data.frame"), function(target){    
    colSums(target)    
})    
     
load("foo.Rdata")    
print(df)    
print(class(df))    
print(showMethods(sumTheColumns))    
sumTheColumns(df)   

From this, R outputs:

[1] "sumTheColumns"
  a b
1 1 2
2 2 3
3 3 4
4 4 5
5 5 6
[1] "tbl_df"     "tbl"        "data.frame"
Function: sumTheColumns (package .GlobalEnv)
target="data.frame"

Error in (function (classes, fdef, mtable)  : 
  unable to find an inherited method for function ‘sumTheColumns’ for signature ‘"tbl_df"’
Calls: sumTheColumns -> <Anonymous>
Execution halted

So as you can see, the tibble is being saved and loaded correct, and it retains its classes, however it no longer dispatches correctly. Interestingly, if you define and call these same methods in the first R session where we create df, these dispatch correctly.

Why is this happening, and how can I fix it?

In case this is an OS-specific bug, here is some output from sessionInfo:

> sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-conda-linux-gnu (64-bit)
Running under: Ubuntu 21.04

CodePudding user response:

Compare the loadedNamespaces() entries in the two situations. I see

> loadedNamespaces()
[1] "compiler"  "graphics"  "utils"     "grDevices" "stats"     "datasets"  "methods"   "base"    

in a clean new session, but after creating df, it grows to

> loadedNamespaces()
 [1] "compiler"  "magrittr"  "ellipsis"  "graphics"  "pillar"    "glue"      "utils"    
 [8] "tibble"    "grDevices" "crayon"    "stats"     "utf8"      "fansi"     "datasets" 
[15] "vctrs"     "methods"   "lifecycle" "pkgconfig" "rlang"     "base"    

So one of those new packages fixes the issue. I'd guess it's tibble itself, and indeed I see the error in the new session, but not after I run loadNamespace("tibble") (which gets everything in the second list).

  • Related