library(data.table)

myunique <- function(df, verbose = FALSE) {
    if (is.data.frame(df)) {
        dt <- data.table(df)
    } else if (is.data.table(df)) {
        dt <- copy(df)
    } else {
        stop("Input should be a data.frame or a data.table")
    }
    
    dt[, i := 1:.N]
    dt[, x := as.character(x)]
    dt[, y := as.character(y)]
    dt_all <- rbind(
        dt,
        dt[, .(x = y, y = x, i = i)]
    )
    
    # a dictionary x(character) -> index(integer)
    dt_g1 <- dt_all[, .(i = list(i)), by = x]
    setkey(dt_g1, x)

    # a dictionary index(integer) -> x(character)
    dt_g2 <- dt_all[, .(x = list(x)), by = i]
    dt_g2[, skip   := FALSE]
    dt_g2[, select := FALSE]
    setkey(dt_g2, i)
    
    while (TRUE) {
        if (length(which(!dt_g2$skip)) > 0) {
            # select first non-skipped index
            cur_i  <- dt_g2[, min(which(!skip))]
            if(verbose) message("current index:\t", cur_i, "/", nrow(dt_g2))
            dt_g2[cur_i, select := TRUE]
            
            # get skipped index vector
            cur_x  <- dt_g2[cur_i, x[[1]]]
            skip_i <- dt_g1[cur_x, unique(do.call(c, i))]
            dt_g2[skip_i, skip := TRUE]
        } else {
            break
        }
    }
    
    # return selected row
    selected_idx <- dt_g2[select == TRUE, i]
    
    return(df[selected_idx, c("x", "y")])
} 

cat("Input\n")
df <- fread("x, y
	1, 2
	1, 3
	2, 4
	2, 6
	3, 2
	3, 7", header = TRUE)
print(df)

cat("Output\n")
myunique(df, verbose = FALSE)
