Извлечение уникальных строк из таблицы данных в R
Я мигрирую из фреймов данных и матриц в таблицы данных, но не нашел решения для извлечения уникальных строк из таблицы данных. Я предполагаю, что что-то мне не хватает в [,J]
примечание, хотя я еще не нашел ответ в FAQ и интро виньетках. Как я могу извлечь уникальные строки, не преобразовывая обратно во фреймы данных?
Вот пример:
library(data.table)
set.seed(123)
a <- matrix(sample(2, 120, replace = TRUE), ncol = 3)
a <- as.data.frame(a)
b <- as.data.table(a)
# Confirm dimensionality
dim(a) # 40 3
dim(b) # 40 3
# Unique rows using all columns
dim(unique(a)) # 8 3
dim(unique(b)) # 34 3
# Unique rows using only a subset of columns
dim(unique(a[,c("V1","V2")])) # 4 2
dim(unique(b[,list(V1,V2)])) # 29 2
Смежный вопрос: является ли это поведение результатом несортировки данных, как в Unix uniq
функционировать?
2 ответа
До data.table v1.9.8 поведение по умолчанию unique.data.table
Метод состоял в том, чтобы использовать ключи для определения столбцов, по которым должны быть возвращены уникальные комбинации. Если key
было NULL
(по умолчанию), можно получить исходный набор данных обратно (как в ситуации с ОП).
По состоянию на data.table 1.9.8+, unique.data.table
Метод использует все столбцы по умолчанию, что соответствует unique.data.frame
в базе R. Для этого используйте ключевые столбцы, явно передать by = key(DT)
в unique
(замена DT
в вызове ключа с именем data.table).
Следовательно, старое поведение было бы что-то вроде
library(data.table) v1.9.7-
set.seed(123)
a <- as.data.frame(matrix(sample(2, 120, replace = TRUE), ncol = 3))
b <- data.table(a, key = names(a))
## key(b)
## [1] "V1" "V2" "V3"
dim(unique(b))
## [1] 8 3
В то время как для data.table v1.9.8+, просто
b <- data.table(a)
dim(unique(b))
## [1] 8 3
## or dim(unique(b, by = key(b)) # in case you have keys you want to use them
Или без копии
setDT(a)
dim(unique(a))
## [1] 8 3
Как упоминал Сет, пакет data.table эволюционировал и теперь предлагает оптимизированные функции для этого.
Для всех, кто не хочет заходить в документацию, вот самый быстрый и самый эффективный способ памяти сделать то, что вы хотите:
uniqueN(a)
И если вы хотите выбрать только подмножество столбцов, вы можете использовать аргумент "by":
uniqueN(a,by = c('V1','V2'))
РЕДАКТИРОВАТЬ: Как упоминалось в комментариях, это будет только количество уникальных строк. Чтобы получить уникальные значения, используйте уникальные вместо:
unique(a)
И для подмножества:
unique(a[c('V1',"V2")], by=c('V1','V2'))