2013-03-05 11 views
19

Ich habe einen 58-Spalten-Datenrahmen, ich muss die Transformation $ log (x_ {i, j} +1) $ auf alle Werte in den ersten 56 Spalten anwenden. Mit welcher Methode könnte ich am effizientesten verfahren? Ich nehme an, dass es etwas gibt, das mir erlauben würde, dies zu tun, anstatt nur einige for-Schleifen zu verwenden, um den gesamten Datenrahmen zu durchlaufen.Funktion auf jeden Wert in einem R-Datenrahmen anwenden

Antwort

18

sollten Sie in der Lage sein, nur auf die Spalten beziehen Sie wollen, und die Operation tun, das heißt:

df.log[,1:56] <- log(df[,1:56]+1) 
+8

oder 'df [1: 56] <- log (df [1: 56] 1)' –

31

alexwhan Antwort für log richtig ist (und wahrscheinlich auch als die richtige Antwort ausgewählt werden sollte). Es funktioniert jedoch so sauber, weil das Protokoll vektorisiert wird. Ich habe den besonderen Schmerz von nicht vektorisierten Funktionen zu oft erlebt. Als ich mit R angefangen habe und die App-Familie nicht gut verstanden habe, habe ich sehr oft auf hässliche Loops zurückgegriffen. Für diejenigen, die auf diese Frage stoßen könnten, die keine vektorisierten Funktionen haben, gebe ich den folgenden Beweis des Konzepts.

#Creating sample data 
df <- as.data.frame(matrix(runif(56 * 56), 56, 56)) 
#Writing an ugly non-vectorized function 
logplusone <- function(x) {log(x[1] + 1)} 
#example code that achieves the desired result, despite the lack of a vectorized function 
df[, 1:56] <- as.data.frame(lapply(df[, 1:56], FUN = function(x) {sapply(x, FUN = logplusone)})) 
#Proof that the results are the same using both methods... 
#Note: I used all.equal rather than all so that the values are tested using machine tolerance for mathematical equivalence. This is probably a non-issue for the current example, but might be relevant with some other testing functions. 
#should evaluate to true 
all.equal(log(df[, 1:56] + 1),as.data.frame(lapply(df[, 1:56], FUN = function(x) {sapply(x, FUN = logplusone)}))) 
+4

Beachten Sie, dass, obwohl es nicht für Ihre speziellen Beispiel funktionieren würde - können Sie rund um eine Funktion erhalten Manchmal wird es nicht vektorisiert, indem man es durch die Funktion "Vectorize" führt. – Dason

+1

Obwohl es funktionieren würde, wenn Sie es doppelt vektorisiert, z. Vektorisieren (Vectorize (logplusone, "x"), "x") – russellpierce

+0

... jedoch finde ich die Vectorized-Funktionen ein wenig auf der schwer zu lesenden Seite, deshalb bevorzuge ich die in meiner Antwort dargestellte Lösung, einfach weil es einfacher ist Ich (wenn ich zurück zum Code gehe) um herauszufinden, wie es funktioniert. – russellpierce

Verwandte Themen