Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove_missings(..., finite = TRUE) removes everything if there is a character column #4284

Closed
jarauh opened this issue Dec 4, 2020 · 1 comment · Fixed by #5188
Closed

Comments

@jarauh
Copy link

jarauh commented Dec 4, 2020

In base-R, character values are not "finite" (i.e. is.finite("a") is FALSE). Therefore, if remove_missings() with finite = TRUE encounters a character column, it throws away everything. Thus, the first of the following two lines raises a warning and returns an empty data.frame, while the second line preserves the input data.frame:

remove_missing(data.frame(foo = "bar", stringsAsFactors = FALSE), finite = TRUE)
remove_missing(data.frame(foo = "bar", stringsAsFactors = TRUE), finite = TRUE)

For me, this led to the following problem that I found extremely difficult to debug: I had a custom stat with required_aes = c("x", "colour"). If the colour-aesthetic was mapped to a factor column, everything worked as expected - non-NA-values of factor variables are finite. If the colour-aesthetic was mapped to a character column, the layer was dropped.

Minimal example:

StatXMean <- ggplot2::ggproto(
  "StatXMean", Stat,
  compute_group = function(data, scales, params, na.rm = FALSE) {
    dplyr::summarize(dplyr::group_by(data, colour),
                     xintercept = mean(x, na.rm = TRUE))
  },  required_aes = c("x", "colour")
)

stat_x_mean <- function(mapping = NULL, data = NULL, geom = "vline",
                        position = "identity", na.rm = FALSE, show.legend = NA,
                        inherit.aes = TRUE, ...) {
  ggplot2::layer(
    stat = StatXMean, data = data, mapping = mapping, geom = geom,
    position = position, show.legend = show.legend, inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...),
  )
}

ggplot(mpg, aes(displ, hwy, colour = drv)) +
  geom_point() + stat_x_mean()

ggplot(mpg, aes(displ, hwy, colour = as.factor(drv))) +
  geom_point() + stat_x_mean()
@teunbrand
Copy link
Collaborator

I too had this problem for the "label" aesthetic. I ended up with a workaround, wrapping the column in a vctrs-class with alternative is.finite() methods, but it isn't pretty. There was mention of an is_finite() generic to handle special cases here: #4189 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants