Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep first row by multiple columns in an R data.table

I'd like to get the first row only from a data.table, grouped by multiple columns.

This is straightforward with a single column, e.g.:

(dt <- data.table(x = c(1, 1, 1, 2),
                  y = c(1, 1, 2, 2),
                  z = c(1, 2, 1, 2)))
#     x y z
# |1: 1 1 1
# |2: 1 1 2
# |3: 1 2 1
# |4: 2 2 2
dt[!duplicated(x)] # Remove rows 2-3
#     x y z
# |1: 1 1 1
# |2: 2 2 2

But none of these approaches work when trying to remove based on two columns; i.e. in this case removing only row 2:

dt[!duplicated(x, y)] # Keeps only original data set
#     x y z
# |1: 1 1 1
# |2: 1 1 2
# |3: 1 2 1
# |4: 2 2 2
dt[!duplicated(list(x, y))] # Same as above
dt[!duplicated(c("x", "y"))] # Same as above
dt[!duplicated(list("x", "y"))] # Same as above
dt[!duplicated(c(x, y))] # Only removes duplicates from first column
#     x y z
# |1: 1 1 1
# |2: 2 2 2

Except for this, which only works in certain cases:

dt[!duplicated(paste0(x, y))]
#     x y z
# |1: 1 1 1
# |2: 1 2 1
# |3: 2 2 2
like image 718
Max Ghenis Avatar asked Jul 23 '14 05:07

Max Ghenis


2 Answers

data.table provides S3 methods for unique, duplicated and anyDuplicated

unique(dt, by = c('x','y'))

will give you what you want.

like image 59
mnel Avatar answered Nov 15 '22 06:11

mnel


data.table does duplicated by key. From ?duplicated.data.table:

 ‘duplicated’ returns a logical vector indicating which rows of a
 ‘data.table’ have duplicate rows (by key).


setkey(dt, x, y)
dt[!duplicated(dt)]
##    x y z
## 1: 1 1 1
## 2: 1 2 1
## 3: 2 2 2
like image 35
Jake Burkhead Avatar answered Nov 15 '22 06:11

Jake Burkhead