2013-03-05 14 views
19

Mam kolumnową ramkę danych 58, muszę zastosować transformację $ log (x_ {i, j} +1) $ do wszystkich wartości w pierwszych 56 kolumnach. Jakiej metody mogę użyć, aby wykonać to najskuteczniej? Zakładam, że jest coś, co pozwoliłoby mi to zrobić, zamiast używać tylko pętli do przepuszczenia całej ramki danych.Zastosuj funkcję do każdej wartości w ramce danych R

Odpowiedz

18

Powinieneś być w stanie po prostu zapoznać się z kolumn, które chcesz, i robić operację, tj odpowiedź

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

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

31

alexwhan jest właśnie dla dziennika (i prawdopodobnie powinien być wybrany jako prawidłową odpowiedź). Jednak działa tak czysto, ponieważ log jest wektoryzowany. Dosyć często doświadczałem specjalnego bólu niewizułowanych funkcji. Kiedy zaczynałem od R i nie rozumiałem dobrze rodziny stosującej, bardzo często uciekałem się do brzydkich pętli. Tak więc, dla tych, którzy mogą natknąć się na to pytanie, którzy nie mają wektoryzowanych funkcji, przedstawiam następujący dowód koncepcji.

#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

Należy zauważyć, że chociaż to nie będzie działać dla konkretnego przykładu - można obejść funkcję czasami nie jest wektoryzowany, uruchamiając go za pomocą funkcji "Wektoryzacji". – Dason

+1

Mimo że zadziała, jeśli podwoisz wektoryzację, np. Vectorize (Vectorize (logplusone, "x"), "x") – russellpierce

+0

... jednak niektóre funkcje wektoryzacji znajdują się trochę po stronie trudnej do odczytania, dlatego preferuję rozwiązanie przedstawione w mojej odpowiedzi po prostu dlatego, że łatwiej jest ja (kiedy wracam do kodu), aby dowiedzieć się, jak to działa. – russellpierce

Powiązane problemy