(Despite all the plus votes, a hybrid of @DavidArenburg and my approaches
res = do.call("paste", c(xy, sep="\r"))
which.max(tabulate(match(res, res)))
might be simple and effective.)
Maybe it seems a little round-about, but a first step is to transform the possibly arbitrary values in the columns of xy
to integers ranging from 1 to the number of unique values in the column
x = match(xy[[1]], unique(xy[[1]]))
y = match(xy[[2]], unique(xy[[2]]))
Then encode the combination of columns to unique values
v = x + (max(x) - 1L) * y
Indexing minimizes the range of values under consideration, and encoding reduces a two-dimensional problem to a single dimension. These steps reduce the space required of any tabulation (as with table()
in other answers) to the minimum, without creating character vectors.
If one wanted to most common occurrence in a single dimension, then one could index and tabulate v
tbl = tabulate(match(v, v))
and find the index of the first occurrence of the maximum value(s), e.g.,
df[which.max(tbl),]
Here's a function to do the magic
whichpairmax <- function(x, y) {
x = match(x, unique(x)); y = match(y, unique(y))
v = x + (max(x) - 1L) * y
which.max(tabulate(match(v, v)))
}
and a couple of tests
> set.seed(123)
> xy[whichpairmax(xy[[1]], xy[[2]]),]
x y
1 1 1
> xy1 = xy[sample(nrow(xy)),]
> xy1[whichpairmax(xy1[[1]], xy1[[2]]),]
x y
1 1 1
> xy1
x y
3 2 5
5 4 9
7 6 12
4 3 6
6 5 10
1 1 1
2 1 1
For an arbitrary data.frame
whichdfmax <- function(df) {
v = integer(nrow(df))
for (col in df) {
col = match(col, unique(col))
v = col + (max(col) - 1L) * match(v, unique(v))
}
which.max(tabulate(match(v, v)))
}