Reputation: 11
After creating a figure, I want to label some points. The labeled points are the result of a filtering process, and may sometimes be empty. I want geom_text to fail gracefully when there are no points to label, (i.e., do nothing). The problem is that rather than failing gracefully, R gives me an error. The error seems entirely dependent on whether I specify hjust in the aesthetic.
This works (in the sense that it does nothing):
library(ggplot2)
library(tidyverse)
ggplot() +
geom_text(
data = tibble(x = numeric(),
y = numeric(),
z = integer()),
mapping = aes(x = x,
y = y,
label = z)
)
Created on 2020-07-23 by the reprex package (v0.3.0)
This does not:
library(ggplot2)
library(tidyverse)
ggplot() +
geom_text(
data = tibble(x = numeric(),
y = numeric(),
z = integer()),
mapping = aes(
x = x,
y = y,
label = z,
hjust = 0
)
)
#> Error: Aesthetics must be either length 1 or the same as the data (1): x, y and label
Created on 2020-07-23 by the reprex package (v0.3.0)
Given that I don't know in advance whether the set of points to be labeled will be empty, how can I specify hjust?
Upvotes: 1
Views: 178
Reputation: 35242
All things mapped inside aes
should be the same length. numeric()
is of zero length, but 0
is of length 1. If aes
does not vary depending on the data, set hjust
instead of mapping it using aes
.
ggplot() +
geom_text(
data = tibble(x = numeric(),
y = numeric(),
z = integer()),
mapping = aes(x = x,
y = y,
label = z),
hjust = 0)
)
Note that I think it should be possible to include hjust = 0
, since arguments of length 1 are supposed to be exempt from the equal length restriction, but apparently this does not work with datasets with 0 observations. This might be considered a bug (at least the error message makes little sense in this case). Regardless, there is no need here to include hjust
inside aes
in the first place, and I would always write it as the code above illustrates.
Upvotes: 2
Reputation: 76402
This is not very pretty but it seems to work. No promises, though.
Works with zero length data.
ggplot() +
geom_text(
data = tibble(x = numeric(),
y = numeric(),
z = integer()),
mapping = aes(
x = x,
y = y,
label = z,
hjust = numeric(if(length(x)) 1 else 0)
)
)
And works with data of length greater than zero.
ggplot() +
geom_text(
data = tibble(x = numeric(1),
y = numeric(1),
z = integer(1)),
mapping = aes(
x = x,
y = y,
label = z,
hjust = numeric(if(length(x)) 1 else 0)
)
)
Upvotes: 0