@@ -98,6 +98,10 @@ StatContour <- ggproto("StatContour", Stat,
98
98
params
99
99
},
100
100
101
+ setup_data = function (data , params ) {
102
+ contour_deduplicate(data )
103
+ },
104
+
101
105
compute_group = function (data , scales , z.range , bins = NULL , binwidth = NULL ,
102
106
breaks = NULL , na.rm = FALSE ) {
103
107
@@ -129,6 +133,10 @@ StatContourFilled <- ggproto("StatContourFilled", Stat,
129
133
params
130
134
},
131
135
136
+ setup_data = function (data , params ) {
137
+ contour_deduplicate(data )
138
+ },
139
+
132
140
compute_group = function (data , scales , z.range , bins = NULL , binwidth = NULL , breaks = NULL , na.rm = FALSE ) {
133
141
breaks <- contour_breaks(z.range , bins , binwidth , breaks )
134
142
@@ -352,3 +360,30 @@ pretty_isoband_levels <- function(isoband_levels, dig.lab = 3) {
352
360
# and open at their upper boundary
353
361
sprintf(" (%s, %s]" , label_low , label_high )
354
362
}
363
+
364
+ # ' De-duplicate data for contours
365
+ # '
366
+ # ' Gives a warning if data has duplicates and throws out duplicated rows.
367
+ # '
368
+ # ' @param data A `data.frame`
369
+ # ' @param check Column names to check for duplicates
370
+ # '
371
+ # ' @return A de-duplicated `data.frame`
372
+ # ' @noRd
373
+ contour_deduplicate <- function (data , check = c(" x" , " y" , " group" , " PANEL" )) {
374
+ check <- intersect(check , names(data ))
375
+ if (length(check ) == 0 ) {
376
+ return (data )
377
+ }
378
+ if (vec_duplicate_any(data [, check , drop = FALSE ])) {
379
+ # We use fromLast here to be consistent with `isoband_z_matrix()` behaviour
380
+ dups <- duplicated(data [, check , drop = FALSE ], fromLast = TRUE )
381
+ data <- data [! dups , , drop = FALSE ]
382
+
383
+ cli :: cli_warn(c(
384
+ " Contour data has duplicated {.field x}, {.field y} coordinates." ,
385
+ i = " {sum(dups)} duplicated row{?s} have been dropped."
386
+ ))
387
+ }
388
+ data
389
+ }
0 commit comments