Skip to content

Unstable hash from unchanged names() attributes created inside R package between interactive and RMarkdown-use #1905

Description

@agranholm

Hello,

This is a cross-post from the mice-package repo,; not sure where it best belongs, but also find it relevant here (amices/mice#754).
Very briefly, my use case was motivated by writing a simple function for re-loading previous results without re-running time consuming code if arguments are unchanged. However, the hashes from seemingly identical objects differ across interactive use and use in a knitted Rmarkdown-document.
In this case, the object is a 'mild'-object which is a list with multiply imputed datasets created by the 'mice' package. It is just a list of data.frames, each named as "1", "2", etc., and a custom class attribute. The names attribute is what causes the problem. It is created by the package as a simple integer vector using 1L: that is then converted using as.character() (see mice:::complete.mids, if relevant).
The object contains no functions or formulas embedding environments or anything of the like.

Here is a minimal reproducible example, also showing that either stripping the names or re-assigning them using a paste0() call fixes the problem:

library(mice)
library(rlang)
imp <- mice(nhanes, m = 2, printFlag = FALSE, seed = 5)
mild <- complete(imp, action = "all", include = FALSE)
hash(mild) # Differs between interactive use and knitr/RMarkdown
hash(unname(mild))  # Stable
# Fix to the issue:
names(mild) <- paste0(names(mild))
hash(mild) # Stable

While this may be an edge case, it was quite difficult to debug, and thus I think it's worth posting here - I imagine it could occur in other contexts too. I used Claude to debug it, and it states that the problem is caused by:
"... the underlying CHARSXP (R's internal cached string objects). Something in how mice allocates strings causes CHARSXPs that are logically identical to serialize differently between an interactive session and a fresh knitr session."
I cannot verify that (that is beyond my knowledge), but the above approach solves it (as does replacing as.character() with paste0() on the integer vector inside the package function).

Version info:
R version 4.4.1 (2024-06-14 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 22631)
rlang_1.2.0
mice_3.19.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions