2015-06-18 4 views
1

я следующие два кадра данных:Заменить строки в одном кадре данных, если они появляются в другом кадре данных

DF1

id V1 V2 V3 
210 4 NA 7 
220 NA NA NA 
230 2 0 1 
240 4 NA NA 
250 1 9 2 
260 6 5 NA 
270 0 NA 3 

df2

id V1 V2 V3 
210 4 3 7 
240 4 3 NA 
270 0 3 3 

df2 это все случаи, когда df1 имеет NA в V2 и по меньшей мере одно числовое значение в V1 или V3. Если это условие выполнено, я изменил NA в V2 на «3».

Теперь я хотел бы вернуть эти dfs вместе. В частности, я хотел бы заменить все строки в df1, которые появляются в df2. Мой ожидаемый результат заключается в следующем:

id V1 V2 V3 
210 4 3 7 
220 NA NA NA 
230 2 0 1 
240 4 3 NA 
250 1 9 2 
260 6 5 NA 
270 0 3 3 

Я посмотрел на this question, но он делает это на основе конкретных значений в ФР. И this question аналогичным образом отвечает, указав фактические значения для замены. Мой реальный df огромен, и все, что я хочу сделать, это поместить два dfs вместе, заменив строки, которые появляются в обоих с df2.

ответ

5

Простой match вызов, который будет идентифицировать экземпляры, которые соответствуют df2$id внутри df1$id (в правильном порядке появления) будет решить эту проблему

df1[match(df2$id, df1$id), ] <- df2 
df1 
# id V1 V2 V3 
# 1 210 4 3 7 
# 2 220 NA NA NA 
# 3 230 2 0 1 
# 4 240 4 3 NA 
# 5 250 1 9 2 
# 6 260 6 5 NA 
# 7 270 0 3 3 

Edit: Как @plafort указывает, вы могли бы во-первых, избегайте создания df2, но я бы пошел с векторизованным подходом, вместо того, чтобы использовать apply. Например

indx <- rowSums(is.na(df1)) != (ncol(df1) - 1) & is.na(df1$V2) 
df1[indx, "V2"] <- 3 
+1

Огромное спасибо, что сработало отлично. Я не знал о матче. Извините, я не могу повышать (я слишком новый), но я дал вам галочку. – szi

+0

См. Также мое редактирование. –

1

я комбинационной синтаксис похож на @DavidArenburg с

df1[df1$id %in% df2$id, ] <- df2 

Может помочь не нужно создавать дополнительный кадр данных? Если df2 создается для заполнения df1, вы можете быстро назначить 3 в соответствующие регионы, не создавая новый фрейм данных.

indx <- apply(df1, 1, function(x) is.na(x[3]) && any(!is.na(x[2:4]))) 
df1$V2[indx] <- 3 
df1 
    id V1 V2 V3 
1 210 4 3 7 
2 220 NA NA NA 
3 230 2 0 1 
4 240 4 3 NA 
5 250 1 9 2 
6 260 6 5 NA 
7 270 0 3 3 
Смежные вопросы