ngreifer / cobalt

Covariate Balance Tables and Plots - An R package for assessing covariate balance
https://ngreifer.github.io/cobalt/
72 stars 11 forks source link

Error: could not find function "str2expression" #37

Closed jimmygillan closed 4 years ago

jimmygillan commented 4 years ago

Hi! Excited to make use of this tool, but running into some basic issues.

Cobalt version 4.2.0 MatchIt version 3.0.2 R version 3.5.3 (2019-03-11) OS linux-gnu

The following code generates the following errror: Error: could not find function "str2expression"

xdata <- data.frame(treat = 1 * (runif(100) <= 0.5),
                    x1 = rnorm(100, 2, 4),
                    x2 = rnorm(100, 5, 2))
matching <- MatchIt::matchit(treat ~ x1 + x2, data = xdata, distance = "mahalanobis", replace = TRUE)
cobalt::bal.plot(matching)

Let me know if I can clarify anything.

Thanks.

ngreifer commented 4 years ago

Hi Jimmy,

This is because you are using an old version of R. You can either update R to a new version or update the backports package. Let me know if either of these fixes fails to solve the problem.

Noah

kthohr commented 4 years ago

Just a suggestion, but if you are relying on functionality introduced in R 3.6, consider incrementing the minimum version of R in your package description file. This will make it easier for users (and admins) to track their R version dependencies.

ngreifer commented 4 years ago

@kthohr I import the backports package, which contains all functions from previous R versions. Normally, importing it is sufficient and this problem doesn't occur. There was a bug in backports that caused the package to fail, propagating to my package. So the problem isn't that users need a higher R version, it's that a package I depended on failed and I didn't catch the bug until I got a few complaints like the one above. As soon as I noticed, I contacted the backports developer and they fixed the bug. cobalt still only requires R 3.3.0. Updating R is just one immediate solution to the problem (and is recommended in general).

kthohr commented 4 years ago

@ngreifer My understanding is that str2expression was a new addition with R 3.6, and is not included in the backports package.

ngreifer commented 4 years ago

@kthohr The backports package contains all the new functions that have been added in recent R versions, including str2expression. Its purpose is to allow package authors to depend on early versions of R while still taking advantage of the functions released in recent versions of R. By importing backports in my R package, I can allow users not to update R while still being able to use the new R functions in my code.

If you look at the documentation for backports, you won't see str2expression or any recently added functions. backports has a special function for use in R packages that imports all the new functions. Users should not have to use backports, or generally even know it exists. This time, due to a bug in it, it was unable to do its job with my package.

kthohr commented 4 years ago

The backports package does not provide all of the new functions that have been added to R since version 3.0.0; and, to my eyes, the backports package description does not claim this level of coverage. I am looking at the source code for backports and it does not include str2expresssion.

I just tested this on a fresh installation of R 3.5.3. I suggest trying this for yourself.

ngreifer commented 4 years ago

@kthohr Wow, you're absolutely right! I'm honestly shocked to find this. I really had assumed they had implemented every new function, but it seems they have forgotten a few. I'm going to manually add str2expression to my package's environment so that old versions of R along with the newest version of backports should work correctly.

Onbackports's README, step 3 is to set the R version in DEPENDS to >=3.0.0, which I took to mean that using backports was sufficient for adding support for all R versions after 3.0.0. Clearly I was wrong.

Thank you so much for looking into this in-depth even as I was inappropriately adamant that I was right. I'm sorry that I was short with you. I'm going to update cobalt shortly.

kthohr commented 4 years ago

No worries. Glad there's an easy fix.

The omission of str2expression (as well as str2lang) from backports is likely due to the somewhat more complicated implementation of these functions in base R; a strict backport would likely require copying chunks of the base C code (do_str2lang, for sure, and probably more).

ngreifer commented 4 years ago

That makes sense. I included the following line in the cobalt source:

 if (getRversion() < 3.6) str2expression <- function(text) parse(text=text, keep.source=FALSE)

Do you think that will be sufficient?

kthohr commented 4 years ago

Looks good to me, and matches the R-level implementation noted in the base R code.