2016-07-12 12 views
1

Ich bin auf einfache Weise der Vereinfachung von Code suchen.Nicht-Standard-Bewertungssyntax mit der Verwendung von Magnetrtr Reverse-Pipe schreiben

Beispiel

Die sqrt Funktion leicht unterhalb auf die Teilmenge der Spalten angewandt werden könnte.

require(magrittr) 
mtcars[,-which(colnames(mtcars) %in% 
       c("mpg", "cyl", "drat", "wt", "carb", 
        "hp", "qsec", "vs", "am", "gear"))] %<>% 
    sqrt 

Problem

Ich habe Interesse an der Anwendung andere Transformationen auf die Teilmenge ohne die Notwendigkeit, wieder die ganze subsetting Sequenz eingeben.

Zum Beispiel der Code:

mtcars[,-which(colnames(mtcars) %in% 
       c("mpg", "cyl", "drat", "wt", "carb", 
        "hp", "qsec", "vs", "am", "gear"))] %<>% 
    .data * 1000 

kehrt Fehler:

Error in function_list[[k]](value) : could not find function ".data" 

Gleiche mit Syntax .. Meine Frage ist: Syntax-weise, wie kann ich den gleichen Effekt wie in der sqrt Funktion erhalten, aber längere Funktion auf die übergebene Teilmenge anwenden?

+0

ersetzen '.data * 1000' durch' \ '* \' (1000) '? um es als eine Funktion und nicht als Operator zu bezeichnen? – Tensibai

+0

@Tensibai Es ist Interesse Ansatz, aber wie kann ich eine Reihe von Operationen effizient übergeben? Multiplikation ist nur ein Beispiel für eine mögliche Nutzung. In der Praxis möchte ich ein paar Dinge für diese Daten. – Konrad

+1

Eine benutzerdefinierte Funktion schreiben, die eine kompatible Ausgabe liefert? (Vektor für Vektor, usw.) oder einfach nur eine anonyme Funktion, wie @Uwe in seiner Antwort gezeigt hat. Ich stimme für die 1, damit Sie die Funktion auch alleine testen können. Ie: '% <>% {. * 10 - 1000} 'zum Beispiel – Tensibai

Antwort

3

Worüber?

sel_cols <- setdiff(colnames(mtcars), 
        c("mpg", "cyl", "drat", "wt", "carb", 
         "hp", "qsec", "vs", "am", "gear")) 
mtcars[, sel_cols] %<>% {sqrt(.) %>% `*`(1000)} 

Oder ein data.table Ansatz?

library(data.table) 
sel_cols <- setdiff(colnames(mtcars), 
        c("mpg", "cyl", "drat", "wt", "carb", 
         "hp", "qsec", "vs", "am", "gear")) 

dt <- as.data.table(mtcars) 
dt[, (sel_cols) := lapply(.SD, sqrt), .SDcols = sel_cols][] 

und mit Rohr kombiniert:

dt <- as.data.table(mtcars) 
dt[, (sel_cols) := lapply(.SD, function(x) {sqrt(x) %>% `*`(1000)}), .SDcols = sel_cols][] 
+0

Danke für die Eingabe, denke ich, dass der erste Vorschlag ist ziemlich ähnlich zu dem, was Tensiabi in seinem Kommentar vorgeschlagen. In Bezug auf den Datentabellen-Ansatz ist es sehr interessant, aber etwas länglich. – Konrad

+0

Das letzte [] ist in den data.table-Ansätzen unnötig, das ursprüngliche dt wird aktualisiert. Vorteil ist die Aktualisierung von data.table ohne Kopieren (bei großen Datensätzen wird vermieden, einen neuen Vektor zu erstellen, der den ursprünglichen ersetzt). Die Verwendung von "lapply" wird benötigt, wenn mehr als eine Spalte zurückgegeben wird, dasselbe gilt für "magritrt". cc @konrad – Tensibai

+0

@Uwe sollten Sie bevorzugen 'setDT (mtcars)' anstelle von 'as.data.table' als setDT wird die data.table zur gleichen Zeit Schlüssel, Cross-Join, etc. – Tensibai