2016-09-11 2 views
-1

Was ist der bevorzugte Weg, dies zu tun?Warum ist `['mit NA so langsam?

Unter Verwendung [ und einem benannten Schlüsselvektor, um einen anderen Vektor zu rekodieren, dachte ich bis vor kurzem, ein robustes und bevorzugtes "R" -Idiom für die Ausführung einer allgemeinen Aufgabe. Gibt es einen besseren Weg, ich sollte das tun?

Details über die Aufgabe: Ich habe einen Zeichenvektor, der eine Länge von ca. 1e6 hat, wobei jedes Element ein Zeichen langen Strings ist. Ich möchte diesen Vektor so umwandeln, dass er numerisch ist ("B", "H", "K", "M"), die Abkürzungen für eine Größenordnung sind (H = hundert, M = Millionen usw.) werden numerisch (H = 100, M = 1e6, usw.) Alle anderen Zeichen, die nicht im Satz von 4 sind, oder NA s, werden 1.

Nach viel Versuch und Irrtum habe ich es auf die Tatsache, dass NA s in der Subsetting-Vektor erheblich verlangsamen den Vorgang. Ich finde das von Natur aus verwirrend, weil es mir scheint, dass die Untermenge mit NA, wenn überhaupt, schneller sein sollte, weil sie nicht einmal den Teilmengenvektor durchsuchen muss, sondern nur eine NA zurückgeben muss.

y <- c("B", "H", "K", "M") 
without_NA <- sample(rep_len(y, 1e6)) 
with_NA <- sample(rep_len(c(y, NA), 1e6)) 

convert_exponent_char_to_numeric <- function(exponent) { 
    exponent_key <- 10^c(2, 3*1:3) 
    names(exponent_key) <- c("H", "K", "M", "B") 

    out <- exponent_key[exponent] 
    out[is.na(out)] <- 1 
    out 
} 

system.time(convert_exponent_char_to_numeric(without_NA)) 
    user system elapsed 
    0.136 0.011 0.147 
system.time(convert_exponent_char_to_numeric(with_NA)) 
    user system elapsed 
303.342 0.691 304.237 
+0

Die Verwendung einer 'data.frame' Nachschlagetabelle beschleunigt Dinge auch, gemäß: http : //stackoverflow.com/a/18457055/496803 – thelatemail

+2

Verwenden Sie 'match':' out <- exponential_key [Übereinstimmung (Exponent, c ("H", "K", "M", "B") )] . – nicola

+0

@nicola - True - Ich vermute, dass die Geschwindigkeit der Lookup-Tabelle aus der Antwort, die ich verlinkt habe, auf der Verwendung von 'match' beruht. – thelatemail

Antwort

2

Hier ist eine Abhilfe, damit er nicht durch den zusätzlichen Code verlangsamt mit NA Erkennung aufgerufen wird:

y   <- c("B", "H", "K", "M") 
without_NA <- sample(rep_len(y, 1e6)) 
with_NA <- sample(rep_len(c(y, NA), 1e6)) 
with_NA[is.na(with_NA)] <- "NA" 

convert_exponent_char_to_numeric <- function(exponent) { 
    exponent_key <- 10^c(2, 3*1:3) 
    exponent_key <- c(exponent_key, 1) 
    names(exponent_key) <- c("H", "K", "M", "B", "NA") 

    out <- exponent_key[exponent] 
    out 
} 

system.time(convert_exponent_char_to_numeric(without_NA)) 
user system elapsed 
    0.03 0.01 0.04 
system.time(convert_exponent_char_to_numeric(with_NA)) 
user system elapsed 
    0.04 0.01 0.05 

Jetzt sind sie beide gut unter 1 Sekunde. Die 1/100 einer zusätzlichen Sekunde Zeit, die mit der with_NA Version genommen wird, ist nur, weil es 5 Niveaus gibt, um auf anstelle von 4 zu passen.