удаление повторяющихся единиц из фрейма данных

Я работаю над большим набором данных с n ковариатами. Многие строки дублируются. Чтобы идентифицировать дубликаты, мне нужно использовать подмножество ковариат для создания идентификационной переменной. То есть (n-x) ковариаты не имеют значения. Я хочу объединить значения ковариатов x, чтобы однозначно идентифицировать наблюдения и устранить дубликаты.

set.seed(1234)
UNIT <- c(1,1,1,1,2,2,2,3,3,3,4,4,4,5,6,6,6)
DATE <- c("1/1/2010","1/1/2010","1/1/2010","1/2/2012","1/2/2009","1/2/2004","1/2/2005","1/2/2005",
      "1/1/2011","1/1/2011","1/1/2011","1/1/2009","1/1/2008","1/1/2008","1/1/2012","1/1/2013",
      "1/1/2012")
OUT1 <- c(300,400,400,400,600,700,700,800,800,800,900,700,700,100,100,100,500)
JUNK1 <- c(rnorm(17,0,1))
JUNK2 <- c(rnorm(17,0,1))

test = data.frame(UNIT,DATE,OUT1,JUNK1,JUNK2)

«тест» — это образец фрейма данных. Переменные, которые мне нужно использовать для уникальной идентификации наблюдений, — это «UNIT», «DATE» и «OUT1». Например,

head(test)
  UNIT     DATE OUT1      JUNK1      JUNK2
1    1 1/1/2010  300 -1.2070657 -0.9111954
2    1 1/1/2010  400  0.2774292 -0.8371717
3    1 1/1/2010  400  1.0844412  2.4158352
4    1 1/2/2012  400 -2.3456977  0.1340882
5    2 1/2/2009  600  0.4291247 -0.4906859
6    2 1/2/2004  700  0.5060559 -0.4405479    

Наблюдения 1 и 4 не дублируются в наборе данных. Наблюдения 2 и 3 дублируются. Новый набор данных, который я хочу создать, будет содержать наблюдения 1 и 4 и только одно из 2 и 3. Я пробовал следующее решение:

subset(test, !duplicated(c(UNIT,DATE,OUT1)))

Что, к сожалению, не помогает:

      UNIT     DATE OUT1       JUNK1      JUNK2
1        1 1/1/2010  300 -1.20706575 -0.9111954
5        2 1/2/2009  600  0.42912469 -0.4906859
8        3 1/2/2005  800 -0.54663186 -0.6937202
11       4 1/1/2011  900 -0.47719270 -1.0236557
14       5 1/1/2008  100  0.06445882  1.1022975
15       6 1/1/2012  100  0.95949406 -0.4755931

Хотя он игнорирует нерелевантные переменные (JUNK1, JUNK2), метод слишком жадный. Новый набор данных должен содержать три наблюдения на единице один, потому что есть три уникальных комбинации UNIT + DATE + OUT1, когда UNIT = 1. Есть ли способ добиться этого без написания функции?


person hubert_farnsworth    schedule 19.03.2013    source источник


Ответы (3)


Вы можете передать data.frame в duplicated

В вашем случае вы хотите передать первые 3 столбца test

 test2 <- test[!duplicated(test[,1:3]),]

Если вы используете большие данные и хотите использовать data.tables, вы можете установить ключ как первые три столбца (из которых вы хотите удалить дубликаты), а затем использовать unique

library(data.table)
DT <- data.table(test)
# set the key
setkey(DT, UNIT,DATE,OUT1)
DTU <- unique(DT)

Дополнительные сведения о дубликатах и ​​таблицах данных см. в разделе Фильтрация дубликатов/ неуникальные строки в data.table

person mnel    schedule 19.03.2013
comment
Поскольку есть тег bigdata, возможно, стоит упомянуть этот пост об удалении дубликатов из data.table - stackoverflow.com/questions/11792527/ - person thelatemail; 19.03.2013

Спасибо! Похоже, мы можем сделать:

test2 <- test[!duplicated(test[,c("OUT1","DATE","UNIT")]),]

и он доставляет товары, а также. Итак, мы можем просто использовать имена столбцов, а не 1:3, и порядок не имеет значения.

person hubert_farnsworth    schedule 19.03.2013
comment
Это ничем не отличается от моего ответа, за исключением того, что я отмечаю, как работает [, что не имеет отношения к компоненту duplicated. - person mnel; 19.03.2013

Вы можете использовать distinct() из пакета dplyr:

library(dplyr)
test %>%
  distinct(UNIT, DATE, OUT1)

Или без трубы %>%:

distinct(test, UNIT, DATE, OUT1)
person Sam Firke    schedule 29.05.2015