заменить значения в кадре данных на основе индексов второго кадра данных R - PullRequest
1 голос
/ 10 февраля 2020

У меня есть следующая задача: заменить значения переменной V1 в кадре данных на значения той же переменной в кадре данных B. Далее я моделирую кадры данных:

set.seed(123)

A<-data.frame(id1=sample(1:10,10),id2=sample(1:10,10),V1=rnorm(10),V2=rnorm(10))
###create dataframe B
B<-A[sample(1:10,5),1:3]
###change values to be updated in df A
B$V1<-rnorm(5)
###create a row which is not in A, to make it more interesting
B<-rbind(B,c(11,12,rnorm(1)))

Теперь я предоставляю неоптимальное решение, которое sh чтобы сделать более чистым

temp<-left_join(A,B,by=c("id1","id2"))
temp[!is.na(temp$V1.y),"V1.x"]<-temp[!is.na(temp$V1.y),"V1.y"]

A<-temp[,setdiff(colnames(temp),"V1.y")]
colnames(A)[colnames(A) %in% "V1.x"]<-"V1"

Было бы желательно избегать создания временных объектов и изменять непосредственно df A. Также решение должно быть масштабируемым, чтобы заменять значения в более чем одном столбце A. Я думаю, что-то вроде

A[expression1,desired_cols]<-B[expression2,desired_cols]

, где expression1 и expression2 предназначены для совпадения индексов в df, а desired_cols являются именами столбцов, которые должны быть заменены

1 Ответ

2 голосов
/ 10 февраля 2020

Мы можем использовать объединение из data.table и обновить столбцы 'A' соответствующим столбцом i. второго набора данных ('B')

library(data.table)
setDT(A)[B,  V1 := i.V1, on = .(id1, id2)]

Если мы заменим несколько столбцы, запишите столбцы для замены

nm1 <- names(A)[3:4]
nm2 <- paste0("i.", nm1)
setDT(A)[B, (nm1) := mget(nm2), on = .(id1, id2)]

Или, если мы используем left_join, тогда coalesce будет лучше

library(dplyr)
left_join(A, B, by = c('id1', 'id2')) %>%
        transmute(id1, id2, V1 = coalesce(V1.y, V1.x), V2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...