2015-12-09 7 views
3

Вот код, чтобы использовать для этого вопроса:отфильтровывать ряды группы, которые не соответствуют критериям

set.seed(1337) 
myDT <- data.table(Key1 = sample(letters, 500, replace = TRUE), 
        Key2 = sample(LETTERS[1:5], 500, TRUE), 
        Data = sample(1:26, 500, replace = TRUE)) 
setkey(myDT, Key1, Key2) 
# showing what myDT looks like 
> myDT 
    Key1 Key2 Data 
    1: a A 6 
    2: a A 3 
    3: a B 2 
    4: a B 20 
    5: a B 13 
---    
496: z D 23 
497: z E 3 
498: z E 18 
499: z E 11 
500: z E 2 

Я хотел бы пару вниз myDT брать только наибольшие значения данных для каждого Key1, Клавишу2 пара. Например. (используя (Key1, Key2) для обозначения пары) для (a, A) Я хотел бы избавиться от строки, где Data равно 3, и сохранить строку, где Data 6. Для (z, E) я хотел бы держите только строку, где данные 18.

При вводе этого вопроса мне пришло решение (которое я опубликую ниже), но, пожалуйста, помогите мне узнать, как вы подходите к этой проблеме.

ответ

5

Мой ответ

myDT[order(-Data), head(.SD, 1), by = .(Key1, Key2)] 
# if you are on 1.9.6 or lower use this one 
myDT[order(-Data), .SD[1], by = .(Key1, Key2)] 

Или от комментариев

unique(myDT[order(-Data)], by = c("Key1", "Key2")) 

Benchmark на 50M строк.

library(dplyr) 
library(data.table) 
library(microbenchmark) 
set.seed(1337) 
n = 5e7 
myDT <- data.table(Key1 = sample(letters, n, replace = TRUE), 
        Key2 = sample(LETTERS[1:5], n, TRUE), 
        Data = sample(1:26, n, replace = TRUE)) 
setkey(myDT, Key1, Key2) 

microbenchmark(times = 10L, 
       CathG = myDT[, .SD[which.max(Data)], by = .(Key1, Key2)], 
       jangorecki = myDT[order(-Data), head(.SD, 1), by = .(Key1, Key2)], 
       jangorecki.keeporder = myDT[order(-Data), head(.SD, 1), keyby = .(Key1, Key2)], 
       nist = myDT %>% group_by(Key1,Key2) %>% summarise(Data = max(Data)), 
       David = unique(myDT[order(-Data)], by = c("Key1", "Key2"))) 

#Unit: milliseconds 
#     expr  min  lq  mean median  uq  max neval 
#    CathG 659.6150 689.3035 733.9177 739.795 780.0075 811.1456 10 
#   jangorecki 2844.7565 3026.3385 3089.6764 3097.332 3219.1951 3343.9919 10 
# jangorecki.keeporder 2935.3733 3194.1606 3232.9297 3214.581 3308.0735 3411.4319 10 
#     nist 803.1921 844.5002 1011.7878 1007.755 1188.6127 1228.3869 10 
#    David 3410.4853 3501.5918 3590.2382 3590.190 3652.8091 3803.9038 10 

Ранее писал тест на небольших данных показывает много разных результатов, так что я бы сказал, что в значительной степени зависит от данных, а не только объем, но и мощность (число уникальных значений) - может быть, даже больше, в некоторых случаев.

4

Другой способ сделать это, основываясь на this Q является:

myDT[, .SD[which.max(Data)], by = .(Key1, Key2)] 
# Key1 Key2 Data 
# 1: a A 6 
# 2: a B 20 
# 3: a C 25 
# 4: a E 7 
# 5: b A 25 
#---    
#119: z A 23 
#120: z B 26 
#121: z C 24 
#122: z D 25 
#123: z E 18 
+0

Это выглядит правильно, но я не могу заставить его закончить. Мои данные имеют 120 тыс. Строк и 64 столбца. Было бы разумно вытащить три столбца, выполнить эту операцию, а затем объединить их обратно? – jks612

+0

Я использовал ссылку, которую вы использовали для эффективной реализации Matt Dowle. Почему эта версия неэффективна? – jks612

+0

@ jks612 '' '' '' .SD' добавляет некоторые накладные расходы, см. Мой ответ и тесты – jangorecki

2

Более быстрый и красивый способ решить эту проблему с помощью dplyr

myDT %>% group_by(Key1,Key2) %>% summarise(Data = max(Data)) 

Чтобы сохранить все существующие столбцы данных , вы можете использовать slice вместо summarise:

myDT %>% group_by(Key1,Key2) %>% slice(which.max(Data)) 

Обратите внимание, что это вернет ровно 1 строку на группу, а в случае связей это будет первая максимальная строка столбца Data.

+0

Как бы вы слились в любые отсутствующие столбцы? myDT <- data.table (Клавиша1 = образец (буквы, 500, заменить = TRUE), Клавиша2 = образец (буквы [1: 5], 500, TRUE), лишние = 1: 500, данных = выборки (1:26, 500, replace = TRUE)) – jks612

+0

@ jks612, см. Обновленный ответ о том, как сохранить другие столбцы –

Смежные вопросы