2015-05-07 2 views
3

У меня есть data.frame с 50 000 строк с некоторыми дубликатами, которые я хотел бы удалить.Удаление дубликатов из фрейма данных очень быстро

SYMBOL   INTENSITY CALL   VALUE 
1  DDR1   2464.3023 P 0.00016023613 
2  RFC2   496.5190 P 0.0193034606 
3 HSPA6   733.4763 P 0.0008046637 
4  PAX8   2138.2882 P 0.0005617505 
5 GUCA1A   176.3272 A 0.1896873022 
6  UBA7   729.6157 P 0.0170004527 
7  DDR1   2464.3023 P 0.0016023613 
8  RFC2   496.5190 P 0.0593034606 
9 HSPA9   733.4763 P 0.0008046637 
10 PAX8   2138.2882 P  0.15617505 
11 GUCA1A2   176.3272 A 0.01896873022 
12 UBA8   729.6157 P 0.0170004527 

Я использовал следующий, чтобы удалить дубликаты. В четвертой колонке я сохранил тот, у кого минимум «VALUE».

dt <- data.table(df) 
WoDuplic <- dt[,.SD[which.min(VALUE)],by=list(SYMBOL)] 

Это служит цели, но очень медленно, она занимает аппроксимационно 10 секунд, чтобы удалить дубликаты из data.frame из выше размерности. Есть ли способ ускорить процесс?

Отредактировано: Вывод выглядит

SYMBOL   INTENSITY CALL   VALUE 
1  DDR1   2464.3023 P 0.00016023613 
2  RFC2   496.5190 P 0.0193034606 
3 HSPA6   733.4763 P 0.0008046637 
4  PAX8   2138.2882 P 0.0005617505 
5 GUCA1A   176.3272 A 0.1896873022 
6  UBA7   729.6157 P 0.0170004527 


9 HSPA9   733.4763 P 0.0008046637 

11 GUCA1A2   176.3272 A 0.01896873022 
12 UBA8   729.6157 P 0.0170004527 
+1

Так они только дублированные WRT первые 3 колонки , это правильно? – jbaums

+1

@ jbaums Не обязательно со всеми, но всегда по первому столбцу –

+1

Как насчет 'setorder (dt, VALUE); дт [! дублируется (SYMBOL)] '? –

ответ

6

Мы могли бы получить индекс строки (.I[which.min(..)), которые имеют минимум «VALUE» для каждого «СИМВОЛА» и используют этот столбец («V1») для su bset набор данных.

library(data.table) 
dt[dt[,.I[which.min(VALUE)],by=list(SYMBOL)]$V1] 

Или, как @DavidArenburg упоминалось, использование setkey будет более эффективным (хотя я не уверен, почему вы получите ошибку с исходными данными)

setkey(dt, VALUE) 
indx <- dt[,.I[1L], by = SYMBOL]$V1 
dt[indx] 
+1

Я думаю, стоит упомянуть 'unique' и' duplicated', поскольку оба они были бы самыми быстрыми наверняка. Я думаю, что 'setkey (dt, VALUE); indx <- dt [, I [1L], by = SYMBOL] $ V1; dt [indx] 'будет также быстрее. –

+0

'system.time ({WoDuplic <- dt [dt [, .I [who.min (VALUE)], by = list (SYMBOL)] $ V1]})' 'пользовательская система истекло 0.124 0.000 0.123' 'system.time ({WoDuplic <- setkey (dt, VALUE); dt [, .SD [1L], by = SYMBOL]})' пользовательская система истекло '0.312 0.004 0.314' –

+0

@AaghazHussain Я думаю, что' setkey 'будет быстрее, если вы выполните его во второй раз – akrun

0

Вы можете использовать агрегат и объединить, чтобы решить эту проблему. Это должно быть очень быстро.

создать пример data.frame

set.seed(123) 
df <- data.frame(gene=rep(letters[1:20],2500),INTENSITY=1:50000,value=runif(50000)) 

получить значение мин для каждого гена

mins <- aggregate(value ~ gene, data = df, FUN = min) 

и слияния дополнительных столбцов

df.min <- merge(mins, df) 
+2

Я предполагаю, что это должно быть очень медленно по сравнению с методом OP – akrun

+0

ОК, вы правы. Намного быстрее. – Jimbou