2016-06-07 20 views
0

Manipulation Ich habe gerade angefangen mit R arbeiten meine Datenmanipulation und Analyse nach Jahren der Verwendung IgorPro zu tun, die niemand in ihrem rechten Verstand so viel Zeit mit dem Schreiben Skripte in verbringen würde, wie ich habe. Es gibt jedoch eine konzeptionelle Diskrepanz zwischen den beiden, die mir Probleme bereitet.Schreibfunktionen für Datenrahmen in R

Ich möchte eine Funktion schreiben, die jede Spalte in einem Datenframe nehme ich füttere es und skaliere es von 0 bis 1. Das kritische Ding hier ist, dass ich die skalierten Daten im Datenrahmen aufwickeln will. In meinem IgorPro Rahmen des Geistes ist, so einfach:

normalize<-function(col){ 
    col<-col/min(col) 
} 

Wenn ich in testdf$testcol setzen, und das Ergebnis auszudrucken, das hat funktioniert, aber die Ergebnisse sind nicht in den Datenrahmen eingebaut. Ein wenig Forschung legt nahe, dass dies daran liegt, dass meine Funktion in einer lokalen Umgebung existiert, und um Dinge außerhalb der lokalen Umgebung zu modifizieren, muss sie mit der globalen Umgebung verbunden sein.

Modifiziert:

normalize<-function(col){ 
    col<-col/min(col) 
    assign("col",col,envir=.GlobalEnv) 
} 

Aber natürlich dies nur spuckt einen neuen Vektor col genannt und mich nicht in meinem Bestreben helfen, die nicht skalierte Daten zu überschreiben.

Kurzes Neuzuweisen des Spaltennamens zu den neu skalierten Daten, was den Punkt, eine Funktion dafür zu schreiben, zunichte macht, wie kann ich die Funktionsausgabe mithilfe der Argumente in der Funktion tatsächlichen Datenrahmen zuweisen?

Schlussbemerkung: Ich schätze jede Eingabe, die die Verwendung von Paketen beinhaltet, die dies für mich tun würden, aber ich habe viel mehr Datenmanipulation zu tun, und ich würde gerne meine eigenen Funktionen schreiben können finde Pakete für alles, also Bonuspunkte, wenn du mir helfen kannst, zu verstehen, wie ich die Funktion selbst schreibe, anstatt mich auf andere eingebaute Funktionen zu verweisen.

+0

Sie den gesamten Datenrahmen und den Spaltenindex (oder der Name) an die Funktion übergeben konnte, und führen Sie die Berechnung – Barranka

+1

Ihre 'normalize' Funktion werden Ihre Daten nicht auf [0,1] skalieren, sondern auf [1, infinity] –

+0

Sie scheinen bezüglich der Semantik "Pass-by-Reference" und "Pass-by-Value" verwirrt zu sein. [R geht nicht per Referenz] (http://stackoverflow.com/questions/2603184/r-pass-by-reference) –

Antwort

2

Ein weiterer beliebter Ansatz wird mit dem dplyr Paket:

df <- df %>% mutate(col = col/min(col) 

col im Datenrahmen df ersetzen würde. Weitere (Basis R) Option ist transform zu verwenden:

df <- transform(df, col = col/min(col)) 

obwohl dies soll in erster Linie für die interaktive Nutzung, es ist nicht für den Einsatz in Funktionen empfohlen.

2

Hier ist eine typische Basis R Methode für Funktionen, um mehrere Spalten einer Datensatzes angewendet wird. Sagen Sie bitte eine data.frame df haben, und Sie wollen alle Vektoren skalieren:

normalize <- function(x) x/min(x) 

Jetzt lapply können Sie durch Ihre data.frame auszuführen:

df[] <- lapply(df, normalize) 

Beachten Sie, dass die [] müssen halten die data.frame-Struktur. Nun nehmen wir Sie einige kategorische Variablen haben, dass Sie nicht

df[, sapply(df, is.numeric)] <- lapply(df[, sapply(df, is.numeric)], normalize) 

oder anzuwenden, um die Funktion zu einer ausgewählten Gruppe von Variablen berühren wollen:

df[, c("var1", "var2", "var5")] <- lapply(df[, c("var1", "var2", "var5")], normalize) 

Ein beliebtes Paket, das könnte es sich lohnen, es auszuprobieren, ist data.table. Es kann für viele Aufgaben viel schneller als Base R sein.

Hier ist eine Methode, um dies in data.table zu tun:

library(data.table) 
setDT(df) 

df[, names(df) := lapply(.SD, normalize)] 
2

Alle anderen Antworten haben es richtig gemacht, wie man die Spalte standardisiert, aber hier ist etwas, was Sie wissen müssen, über die spezielle Lösung hinaus, was Sie in diesem Fall tun möchten.

Die wesentliche Antwort, warum Ihr Code nicht funktioniert, ist, dass Sie das Objekt, das Sie manipulieren, nicht innerhalb der Funktion zurückgeben.

normalize<-function(col){ 
    col<-col/min(col) 
    return(col) 
}