Much faster solution than sequential iteration (if discontinuities are sparse):
sortForMaxContY <- function(D,initialY){
n <- nrow(D)
D <- D[order(D$x),]
xChanges <- D$x[-1]!=D$x[-n]
isLastOfXVal <- c(xChanges,T)
rankOfXVal <- cumsum(c(T,xChanges))
oldFinalYs <- NA
finalYs <- D$y[isLastOfXVal]
while(!identical(finalYs,oldFinalYs)){
finalYOfPrecedingXVal <- c(initialY,finalYs)[rankOfXVal]
oldFinalYs <- finalYs
D <- D[order(D$x,xor(finalYOfPrecedingXVal,D$y)),]
finalYs <- D$y[isLastOfXVal]
}
return(D)
}
One of sortForMaxContY(D,T)
and sortForMaxContY(D,F)
is the optimum, and the other usually is too, depending on the data.