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;
## Index Ind_A Ind_B
## 1 1 1 0
## 2 2 0 0
## 3 3 1 1
## 4 4 1 0
Die wichtigste Änderung in Ihrem bearbeiten ist, dass indicator$Index
jetzt tut nicht eindeutige Werte (zumindest nicht auf eigene) enthalten, so dass eine einfache match()
values$Index
-indicator$Index
unzureichend ist. Stattdessen müssen wir einen outer()
Gleichheitstest sowohl auf Index
als auch auf Index2
ausführen, um eine Matrix von logischen Daten zu erhalten, die angeben, welche Zeilen in indicator
Zeile values
auf beiden Schlüsseln übereinstimmen. Unter der Annahme, dass der zweispaltige zusammengesetzte Schlüssel eindeutig ist, können wir dann den Zeilenindex in indicator
aus dem linearen (Vektor-) Index berechnen, der von which()
zurückgegeben wird.
indicator[cbind((which(outer(values$Index,indicator$Index,`==`)&outer(values$Index2,indicator$Index2,`==`))-1)%/%nrow(values)+1,match(values$Indicators,names(indicator)))] <- 1;
indicator;
## Index Index2 Ind_A Ind_B
## 1 1 10 1 1
## 2 1 11 1 0
## 3 2 10 0 1
## 4 2 12 1 0
## 5 3 10 1 0
## 6 3 12 1 0
## 7 4 10 1 1
## 8 4 12 1 0
Hier ist eine andere Lösung mit merge()
:
indicator[cbind(merge(values,cbind(indicator,row=1:nrow(indicator)))$row,match(values$Indicators,names(indicator)))] <- 1;
indicator;
## Index Index2 Ind_A Ind_B
## 1 1 10 1 1
## 2 1 11 1 0
## 3 2 10 0 1
## 4 2 12 1 0
## 5 3 10 1 0
## 6 3 12 1 0
## 7 4 10 1 1
## 8 4 12 1 0
Leistung
Die erste Lösung performanter ist:
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()); });
## user system elapsed
## 2.032 0.000 2.041
system.time({ replicate(N,first()); });
## user system elapsed
## 2.047 0.000 2.038
system.time({ replicate(N,second()); });
## user system elapsed
## 12.578 0.000 12.592
system.time({ replicate(N,second()); });
## user system elapsed
## 12.64 0.00 12.66
Sie sollten erwägen eine neue Frage aus der in Ihrem bearbeiten beschriebene Situation zu machen. – Frank
@Frank Danke Ich habe http: // stackoverflow.com/questions/30243920/An-effiziente-Weg-zu-Multiple-Indikator-Variablen-pro-Zeile-mit-Composite – lapolonio