Для этого вы можете использовать силу match (), если имена в df1 $ V1 уникальны:
#some data
df1 <- data.frame(
V1 = rep(c("A","B"),each=3),
V2 = rep(LETTERS[1:3],2)
)
df2 <- data.frame(V1=LETTERS[1:3],Va=1:3,Vb=3:1)
out <- cbind(df1,
df2[match(df1$V1,df2$V1),-1],
df2[match(df1$V2,df2$V1),-1]
)
names(out)[3:6] <- c("Va1","Vb1","Va2","Vb2")
rownames(out) <- 1:nrow(out)
Дает
> out
V1 V2 Va1 Vb1 Va2 Vb2
1 A A 1 3 1 3
2 A B 1 3 2 2
3 A C 1 3 3 1
4 B A 2 2 1 3
5 B B 2 2 2 2
6 B C 2 2 3 1
Вам придется переименоватьстолбцы вручную, так как вы получите несколько столбцов с одинаковым именем.Хотя это технически возможно в фрейме данных, это может вызвать проблемы позже.Вы можете автоматизировать это, используя что-то вроде:
names(out) <-
c("V1","V2",
sapply(names(df2)[2:3],paste,1:2,sep="")
)
РЕДАКТИРОВАТЬ: для больших фреймов данных преобразование в матрицы имеет еще одно огромное отличие.Нужно обратить внимание на внутренние изменения в типе для различных переменных.Ускорение связано с тем, что cbind и merge занимают много времени для определения правильных типов для каждой переменной.
Со следующими данными и функциями:
n <- 1e5
df1 <- data.frame(V1 = rep(LETTERS,each=n),V2 = rep(LETTERS,n),
stringsAsFactors=FALSE)
df2 <- data.frame(V1=LETTERS,Va=1:26,Vb=26:1,stringsAsFactors=FALSE)
fast_JM <- function(df1,df2){
out <- cbind(
as.matrix(df2[,-1])[match(df1$V1,df2$V1),],
as.matrix(df2[,-1])[match(df1$V2,df2$V1),]
)
out <- as.data.frame(out)
names(out) <- sapply(names(df2)[2:3],paste,1:2,sep="")
out$V1 <- df1$V1
out$V2 <- df1$V2
out
}
slow_JM <- function(df1,df2){
out <- cbind(df1,
df2[match(df1$V1,df2$V1),-1],
df2[match(df1$V2,df2$V1),-1]
)
names(out)[3:6] <- c("Va1","Vb1","Va2","Vb2")
out
}
double_merge <- function(df1,df2){
merge(merge(df1, df2), df2, by.x = "V2", by.y = "V1", suffixes = c("1", "2"))
}
эталоном становится:
require(rbenchmark)
benchmark(fast_JM(df1,df2),slow_JM(df1,df2),double_merge(df1,df2),
replications=1,columns=c("test","elapsed","relative"),order="relative")
test elapsed relative
1 fast_JM(df1, df2) 0.89 1.00000
2 slow_JM(df1, df2) 12.54 14.08989
3 double_merge(df1, df2) 42.50 47.75281
Таким образом, ускорение более чем в 40 раз по сравнениюдо двойного слияния и более чем в 10 раз по сравнению с использованием фреймов данных.