Wernicke
Wernicke

Reputation: 77

function not found although package is loaded - R

I have been working with an imputed data set using the MICE package (versions 2.2-3.3) in R (versions 3.3-3.5). I am now trying to add some variables to the imputed data set, which historically have worked fine using cbind.mids() (in this specific case, it is a Surv object variable from the Surv function). This does not, for some reason, work anymore. Although the mice package is loaded, the function cbind.mids() is not found.

Minimal example:

> library(mice)
Loading required package: lattice

Attaching package: ‘mice’

The following objects are masked from ‘package:base’:

cbind, rbind

> cbind.mids()
Error in cbind.mids() : could not find function "cbind.mids"

Note 1: ?cbind.mids still works and finds the help file. Using only cbind() from the mice package does not work either, It will merge my new variables to the mids object, but they do not work in subsequent analysis.

Note 2: I have tried reinstalling R, mice and Rstudio. I do not get any other error messages for guidance.

Does anyone know why it behaves like this? Is the cbind.mids() function for some reason removed or is it a problem with my system?

Upvotes: 0

Views: 1754

Answers (3)

IRTFM
IRTFM

Reputation: 263421

Now I can answer the original question and the one I asked Konrad. The mice function masks the base S3 cbind function. There was notice of this as I loaded mice, but I didn't pay sufficient attention to it. So any call to cbind after mice has been loaded first goes through this function (rather than the usual S3 UseMethod-dispatch). I think it's more helpful to think that the usual S3-dispatch is "masked" or hidden from view, rather than saying it is "broken":

> `cbind`
function (...) 
{
    if (is.null(attr(list(...)[[1]], "class"))) 
        return(base::cbind(...))
    if ("mids" %in% attr(list(...)[[1]], "class")) 
        return(cbind.mids(...))
    else return(base::cbind(...))
}
<bytecode: 0x1b399908>
<environment: namespace:mice>

So the original S3 functions are there, just lying under the surface in whatever namespace they were defined in:

> getS3method('cbind', 'mids')
Error in getS3method("cbind", "mids") : S3 method 'cbind.mids' not found
> getS3method('cbind', 'data.frame')
function (..., deparse.level = 1) 
{
    if (!identical(class(..1), "data.frame")) 
        for (x in list(...)) {
            if (inherits(x, "data.table")) 
                return(data.table::data.table(...))
        }
    data.frame(..., check.names = FALSE)
}
<bytecode: 0x51233f0>
<environment: namespace:base>

> getS3method('cbind', 'sf')
function (..., deparse.level = 1, sf_column_name = NULL) 
{
    st_sf(data.frame(...), sf_column_name = sf_column_name)
}
<bytecode: 0xb380a80>
<environment: namespace:sf>

(I'm not sure this answers any change in behavior from previous versions of the mice package. For that one would first go to news(pac='mice')

V2.41    10jul2017 SvB
ADDED    New feature: `where`argument to mice
ADDED    New `wy` argument to imputation functions
ADDED    New mice.impute.2l.sys(), author Shahab Jolani
UPDATE   Many simplifications and code enhancements
FIXED    Broken cbind() function

It doesn't say in what manner the mice::cbind function broke or into how many pieces.

V2.33    11apr2017 SvB
CHANGED  Stylistic changes to mice function (thanks Ben Ogorek)
CHANGED  calls to cbind.mids() replaced by calls to cbind()

Upvotes: 1

Gainz
Gainz

Reputation: 1771

the cbind.mids() is ''in'' the cbind() function from the mice package. In R console, write ?cbind, then choose the one from the mice package, then at the bottom (see also) click on cbind.mids and look at the examples. You'll see that the function cbind is doing cbind.mids automatically when needed. At least I am pretty sure this the case, just like the merge function in data.table is name merge.data.table but you are only writing merge when using the function. Tell me if it works for you.

Edit : Try using the format from the example. If it doesn't work then maybe the function is not updated/used anymore in the package?

Edit 2 : Official note on mice::cbind() :

"The standard base::cbind() and base::rbind() always dispatch to base::cbind.data.frame() or base::rbind.data.frame() if one of the arguments is a data.frame. The versions defined in the mice package intercept the user command and test whether the first argument has class "mids". If so, function calls cbind.mids(), respectively rbind.mids(). In all other cases, the call is forwarded to standard functions in the base package."

Upvotes: 1

Franziska W.
Franziska W.

Reputation: 356

I would use function "cbind" as described in the R documentation of function "cbind.mids {mice}". It works also with Surv object variables.

require(mice);
require(survival);

with(lung, Surv(time, status))
cbind(
  x = Surv(heart$start, heart$stop, heart$event)
  ,y = Surv(heart$start, heart$stop, heart$event));

Upvotes: 1

Related Questions