Злиття кадрів даних в R на попередньо відсортованому стовпці?

Я зазвичай працюю з великими файлами даних, які досить добре сортовані (або їх можна легко сортувати).

Враховуючи два кадри даних, обидва сортуються за "користувачем"

some.data    
user   

І я запускаю m = merge (some.data, user) , я отримую результат як:

m =     

І все це добре.

Але merge не використовує переваги цих файлів даних, які сортуються в загальному стовпці, що робить об'єднання досить складним процесором/пам'яттю. Однак, це злиття можна здійснити в O (n)

Мені цікаво, чи існує спосіб у R, щоб провести ефективне злиття на відсортованих наборах даних?

6
Якщо я не можу придумати щось більш істотне, щоб додати, відповідь Ніка - це те, що я рекомендую. Єдина річ полягає в тому, що під час злиття добре очистити будь-які невикористовувані або непотрібні змінні: в результаті створення нового кадру даних вам доведеться переміщати набагато більше даних. Я часто створюю тимчасові змінні в кадрі даних (або таблицю даних), а потім об'єдную їх (наприклад, myDT $ tmpVar = NULL ) перед об'єднанням або сортуванням об'єктів.
додано Автор Iterator, джерело

2 Відповіді

Я не маю ніякого досвіду з цим, але наскільки я знаю, це одне з проблем, які було розроблено для пакету data.table .

Для більшості практичних цілей data.table = data.frame + index . Внаслідок цього, коли використовується правильно, це покращує виконання небагатьох великих операцій.

Існує небезпека того, що перетворення вашого data.frame в data.table (тобто додавання індексу) може зайняти деякий час (хоча я очікую, що це буде оптимізовано). але як тільки ви це зробите, такі функції, як злиття, можуть легко використовувати індекс для підвищення продуктивності.

5
додано
Це хороша відповідь. Щоб уточнити: додавання індексу насправді не відбувається - data.table використовує самі дані для створення ключів (хоча обмежується цілими чи цифрами, цілі числа, AFAIK). Для цього він сортує дані за допомогою зазначеного ключа змінних . Якщо дані вже переважно сортуються цими ключами, то повний сорт досить швидко. Проте, не потрібно вказати ключі - все ще можна використовувати merge .
додано Автор Iterator, джерело
(Продовження) З цих та інших причин, всі пов'язані з швидкістю, я нещодавно перемикав багато кадрів даних на таблиці даних і не пошкодував про це - це швидко, і я порівняв його з 10 альтернативами. Без цього я б писав багато коду в C або C ++, щоб зробити лише частину того, що я міг би зробити з ним. (Погляд на цілу групу питань, які я опублікував, зробить це процес навчання досить чітким ;-))
додано Автор Iterator, джерело

Якщо ваш набір загальних ключів/індексів повністю перекривається, це ...

Reduce(`&`, user$user.id %in% some.data$user.id)

... повертає ІСТИНА, і вони, як ви сказали, сортували, , і немає копій ключів , тоді проблема злиття зводиться до додавання стовпців до data.frame. Щось у лініях уздовж ...

library(log4r)

t1 <- system.time(z <- merge(user, some.data, by='user.id'))

info(my.logger, paste('Elapsed time with merge():', t1['elapsed']))

t2 <- Sys.time()

r <- data.frame(user.id=user$user.id, V1.x=user$V1, V2.x=user$V2)

r[,names(some.data)] <- some.data[,names(some.data)

t3 <- Sys.time()

info(my.logger, paste('Elapsed time without:', t3-t2))

Якщо припущень, наведених вище, не виконується, то він стає дещо менш набором об'єднань обох наборів ключових слів, функцією перекладу, наповненням Н.А.), але припущення, що зливається і збігається, лише дає вам великий шлях вперед.

Зверніть увагу також на те, що часування секундного підходу є необ'єктивним, оскільки він двічі викликає Sys.time (), на відміну від часу з'єднання (), який викликає system.time() і лише один раз. (Вибачте моє кульгаве використання націнки на S.O.)

0
додано