2012-04-12 2 views
1

Я пытаюсь объединить два кадра данных с уникальным идентификатором и годом. В языке SQL я пытаюсь сделать левое внешнее соединение, поэтому в слиянии это all.x = TRUE. Некоторые элементы y-фрейма не имеют всех значений (уникальные комбинации id, year) в x DF. В случае отсутствия совпадения я хочу объединить строку из фрейма данных y, который имеет тот же уникальный идентификатор, что и в фрейме данных x, но с использованием первого года, который у меня есть до пропавшего. Любые предложения о том, как подойти к этому слиянию? Большое спасибо!Замена слияния NA

Редактировать Хотел сделать его более конкретными

Dataframe х:

Id year var1 
1 2010 100 
1 2011 105 
1 2012 110 
2 2010 100 
2 2011 105 
2 2012 106 

Dataframe у:

Id year var2 var3 
1 2010 5  7 
1 2011 10  8 
2 2010 9  6 

Желаемый объединения:

Id year var1 var2 var3 
1 2010 100  5  7 
1 2011 105  10  8 
1 2012 110  10  8 
2 2010 100  9  6 
2 2011 105  9  6 
2 2012 106  9  6 
+0

Я хотел бы предложить вам опубликовать воспроизводимый код. Вы можете сделать это, используя 'head (x dataframe, 10)' и 'head (y dataframe, 10)' и строки кода, которые вы пытаетесь использовать. это гораздо более полезно для диагностики вашей проблемы и предоставления точных и эффективных решений. –

ответ

2

я хотел бы сделать это в два этапа:

> out <- merge(x, y, all.x=T) 
> out 
    Id year var1 var2 var3 
1 1 2010 100 5 7 
2 1 2011 105 10 8 
3 1 2012 110 NA NA 
4 2 2010 100 9 6 
5 2 2011 105 NA NA 
6 2 2012 106 NA NA 

Затем используйте na.locf из zoo пакета:

library(zoo) 

> apply(out, 2, na.locf) 
    Id year var1 var2 var3 
[1,] 1 2010 100 5 7 
[2,] 1 2011 105 10 8 
[3,] 1 2012 110 10 8 
[4,] 2 2010 100 9 6 
[5,] 2 2011 105 9 6 
[6,] 2 2012 106 9 6 

, и это может быть принужден к data.frame достаточно легко.

> as.data.frame(apply(out, 2, na.locf)) 
    Id year var1 var2 var3 
1 1 2010 100 5 7 
2 1 2011 105 10 8 
3 1 2012 110 10 8 
4 2 2010 100 9 6 
5 2 2011 105 9 6 
6 2 2012 106 9 6 
+0

Ничего себе, это очень приятно, спасибо. Нужно ли беспокоиться о порядке вывода данных? Похоже, что na.locf учитывает какую-либо структуру в отношении идентификаторов и лет, а просто поднимает данные в предыдущие значения. –

+0

Да, 'na.locf' просто копирует предыдущие значения без учета вашего' Id' или 'year'. Кроме того, если 'y' содержит год, который ранее не был сопоставлен (но был бы подходящим кандидатом на запись в' x'), это не поймало бы его. –

+0

, когда вы вызываете 'merge' на' data.frames', есть аргумент по умолчанию 'sort = TRUE', который сортирует по объединенному столбцу (в вашем случае вы полагаетесь на пересечение имен для этого). Если вы хотите, чтобы он отсортировался по-другому, вы можете сделать это до шага 'na.locf', используя' order': 'out [order (out $ var1),]' или что угодно. Но вы правы, 'na.locf' работает только с вектором, который вы отправляете, и не знает остальной части' data.frame'. – Justin

1

Это не использует merge, но петли через ряды x одного в то время, чтобы найти подходящий матч в y. Наверное, неэффективно, но он работает.

do.call(rbind, 
    lapply(seq(length=nrow(x)), function(r) { 
    yid <- y[y$Id==x$Id[r],] 
    yeardiff <- x$year[r] - yid$year 
    yeardiff[yeardiff < 0] <- NA 
    cbind(x[r,], yid[which.min(yeardiff),]) 
})) 

В результате

Id year var1 Id year var2 var3 
1 1 2010 100 1 2010 5 7 
2 1 2011 105 1 2011 10 8 
3 1 2012 110 1 2011 10 8 
4 2 2010 100 2 2010 9 6 
5 2 2011 105 2 2010 9 6 
6 2 2012 106 2 2010 9 6 
+0

Спасибо за этот пример. Его приятно иметь как на всякий случай, я хочу сделать что-то немного другое. –

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