indicator <- data.frame(Index=1:4,Ind_A=rep(0,4),Ind_B=rep(0,4)); values <- data.frame(Index=c(1,3,3,4),Indicators=c('Ind_A','Ind_A','Ind_B','Ind_A')); indicator[cbind(match(values$Index,indicator$Index),match(values$Indicators,names(indicator)))] <- 1; indicator;
The most significant change in your editing is that indicator$Index now does not contain unique values ββ(at least not by itself), so a simple match() from values$Index to indicator$Index not enough. Instead, we should run the outer() equality test on Index and Index2 to get a matrix of logic elements representing which rows in indicator correspond to each row of values for both keys. Assuming that the combined key with two columns is unique, we can calculate the row index in indicator from the linear (vector) index returned by which() .
indicator[cbind((which(outer(values$Index,indicator$Index,`==`)&outer(values$Index2,indicator$Index2,`==`))-1)%/%nrow(values)+1,match(values$Indicators,names(indicator)))] <- 1; indicator;
Here is another solution using merge() :
indicator[cbind(merge(values,cbind(indicator,row=1:nrow(indicator)))$row,match(values$Indicators,names(indicator)))] <- 1; indicator;
Performance
The first solution is more productive:
first <- function() indicator[cbind((which(outer(values$Index,indicator$Index,`==`)&outer(values$Index2,indicator$Index2,`==`))-1)%/%nrow(values)+1,match(values$Indicators,names(indicator)))] <<- 1; second <- function() indicator[cbind(merge(values,cbind(indicator,row=1:nrow(indicator)))$row,match(values$Indicators,names(indicator)))] <<- 1; N <- 10000; system.time({ replicate(N,first()); });