2015-10-02 1 views
-1

Я создал петлю для присвоения значений столбцов из data.frame в колонку другого data.frame на основе некоторых условий:Ускорить петлю для присвоения значений из нескольких данных фреймов

for (lineTab1 in 1 : dim(tab1)[1]) { 
    for (lineTab2 in 1 : dim(tab2)[1]) { 
    if (tab1$id[lineTab1] == tab2$id[lineTab2]) & 
    tab1$year[lineTab1] == tab2$year[lineTab2])) { 
    tab1$region[lineTab1] <- tab2$region[lineTab2]) } 
} 
} 

Моих петли слишком медленно! Первый data.frame (tab1) имеет 60 000 000 наблюдений, а второй data.frame (tab2) имеет 1000 наблюдений. Есть ли способ ускорить эти петли?

ответ

4

Похоже, вы пытаетесь слить. В базе R есть функция merge, которая, вероятно, сделает все, что вам нужно, без труда.

Обратите внимание, что я предполагаю, что tab2 - это просто таблица поиска для области id/year. Если есть другие столбцы в tab2, то вы можете использовать либо data.table решение ниже, или удалить оставшиеся столбцы из tab2

В базовой R, можно ожидать, что это слияние принять ~ 3 минуты, на основании некоторых экспериментов.

Использование библиотеки dplyr, это сокращается примерно до 5 секунд, как left_join(tab1, tab2).

Использование библиотеки data.table, это занимает всего около секунды, хотя время установки немного выше:

setDT(tab1) 
setDT(tab2) 
system.time(tab1[tab2, region := i.region, on=c("id","year")]) 

Для синхронизации данных я использовал образец данных, генерируемых в

tab2 <- expand.grid(id=1:10, year=2000:2010) 
tab2$region <- rnorm(110) 
tab1 <- data.frame(id=sample(1:10, 6e7, replace=T), year=sample(2000:2010, 6e7, replace=T)) 
+2

... хотя с 60 миллионами записей возможно ** data.table ** или ** dplyr ** было бы предпочтительнее. – joran

+0

Эй, я обновил код для решения 'data.table', чтобы отразить более распространенное использование. Я не обновлял ваше время. В частности, обратите внимание, что OP действительно не требует полного слияния, поэтому эти коды, вероятно, будут намного медленнее, если есть другие столбцы, особенно в 'tab2'. – MichaelChirico

+0

@MichaelChirico Я не так знаком с 'data.table', как с' dplyr', но у вашего редактирования был 'i.region', который дал мне ошибку. Есть ли что-то, что мне не хватает, или это просто опечатка – user295691