Question Details

No question body available.

Tags

r ggplot2

Answers (2)

March 6, 2026 Score: 1 Rep: 168,538 Quality: Medium Completeness: 80%

Another way is to get just the first row for each consecutive label. We can do that before the call to plot, or one way that can work better at times (especially if ggplot() is after a sequence/pipe of data-changing commands) is to change data= for a particular geom using its rlang-~ faux-function interface.

BTW, it's better to not use dt$ within ggplot aesthetics.

Working code:

ggplot(dt, aes(x = year, y = value)) +
  geomline() +
  scaleycontinuous(labels = dt$label, breaks = dt$value) + 
  geomtext_repel(
    # removed dt$ from dt$label
    aes(label = label),
    # filter/change the data ggplot knows, effective for just this geom
    data = ~ .x[, .SD[1,], .(label, rleid(label))]
  )

The .x of data = ~ .x[...] is replaced with the core data that ggplot "knows" within the plot-space.

ggplot code with one entry per change-event

(Small caveat: the use of rleid assumes that the data is ordered within the frame. Easy to work through if that is not guaranteed, either by forcing the order or perhaps some other techniques.)

March 6, 2026 Score: 0 Rep: 45 Quality: Low Completeness: 60%

ugly solution:

I actually have figured out how to do it, but it feels really inefficient/ugly. I basically created a column that lags column label and then created another column comparing labeland lagLabel. That's how I made the second graph above. But I'd like to see if there's a more elegant way to do this!

Reproducible ugly solution:

ref %
  mutate(lagLabel = lag(label)) %>%
  mutate(changeLabel = ifelse(label == lagLabel, NA, label))

g