2016-05-26 16 views
3

Ich habe ein Wörterbuch (Tabelle Tabelle mit 2 Spalten), wo einige der Werte mit einigen der Schlüssel übereinstimmen. In diesen Situationen möchte ich die Werte durch den Wert des Schlüssels ersetzen, auf den sie zeigen.R Eliminierung mehrerer Lookups in einem Wörterbuch

Beispiel:

Key, Value 
"aa", "ac" 
"ab", "ba" 
"ac", "ad" 
"ad", "da" 
"ae", "ac" 

Was ich versuche zu produzieren:

Key, Value 
"aa", "da" 
"ab", "ba" 
"ac", "da" 
"ad", "da" 
"ae", "da" 

Was ich versucht habe: nur

dict <- data.frame(key=c("aa","ab","ac","ad","ae"),value=c("ac","ba","ad","da","ac")) 
repeat { 
    needs_replacing <- dict[dict$Value %in% dict$Key,] 
    if(nrow(needs_replacing) == 0) { 
     break; 
    } 
    replacements <- dict[dict$Key %in% needs_replacing$Value,] 
    dict[dict$Value %in% dict$Key,]$Value <- replacements[?????,]$Value 
} 

Das Problem, das ich habe, ist, dass replacements hat drei Werte in der ersten Iteration, aber ich versuche, sie zu erweitern, um vier Werte zu ersetzen. Ich weiß, dass Sie es mit Indizes unterteilen können, aber sie zu bekommen ist eine Art von Schmerz, und ich bin mir nur nicht sicher, ob es einen besseren Weg gibt, um das zu erreichen, was ich versuche.

+0

Sollten nicht die ersten und letzten Werte in der Ausgabe "Value" "ad" sein? –

+0

Nein, der springende Punkt ist, es wiederholt zu tun, um alle Ketten zu glätten und nur eine einzige Suche zu haben. aa -> ac -> ad -> da, also sollten alle Schlüssel in der Kette direkt auf das Ende der Kette zeigen –

+0

Ich sehe. Vielleicht suchen Sie nach einem der Link-Pakete, leider, –

Antwort

3

Wir müssen nur die Schleife anpassen. Im replacements Ausdruck ist match besser als %in%, weil es den Index der Spiele zurück, während die letztere Logicals Agnostiker Standort zurück:

repeat { 
    needs_replacing <- dict$value[dict$value %in% dict$key] 
    if(length(needs_replacing) == 0) { 
    break; 
    } 
    replacements <- dict$value[match(needs_replacing, dict$key)] 
    dict$value[dict$value %in% dict$key] <- replacements 
} 
dict 
# key value 
# 1 aa da 
# 2 ab ba 
# 3 ac da 
# 4 ad da 
# 5 ae da 
0

ich denke, das wird funktionieren, es erzeugt die gewünschte Ausgabe.

while(length(dict[dict$Value %in% dict$Key, "Value"]) > 0) { 
    dict[dict$Value %in% dict$Key, "Value"] <- 
    dict[match(dict[dict$Value %in% dict$Key, "Value"], dict$Key), "Value"] 
}