2013-03-05 19 views
19

Ho un dataframe di 58 colonne, ho bisogno di applicare la trasformazione $ log (x_ {i, j} +1) $ a tutti i valori nelle prime 56 colonne. Quale metodo potrei usare per andare su questo in modo più efficiente? Presumo che ci sia qualcosa che mi permetterebbe di fare questo piuttosto che usare solo alcuni loop per scorrere l'intero dataframe.Applicare la funzione a ogni valore in un dataframe R

risposta

18

Si dovrebbe essere in grado di fare riferimento solo alle colonne che si desidera, e fare l'operazione, vale a dire: la risposta

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

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

31

di alexwhan è giusto per log (e dovrebbe probabilmente essere selezionata come la risposta corretta). Tuttavia, funziona in modo così pulito perché il log è vettorializzato. Ho sperimentato il dolore speciale delle funzioni non vettorializzate troppo spesso. Quando ho iniziato con R, e non ho capito bene la famiglia applicata, ho fatto ricorso a brutti loop molto spesso. Quindi, per gli scopi di coloro che potrebbero imbattersi in questa domanda che non ha funzioni vettorializzate, fornisco la seguente dimostrazione di concetto.

#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

Nota che, anche se non avrebbe funzionato per il vostro esempio particolare - si può andare in giro una funzione non essendo vettorizzati a volte eseguendolo attraverso la funzione 'Vectorize'. – Dason

+1

Anche se funzionerebbe se si raddoppiano Vectorized, ad es. Vectorize (Vectorize (logplusone, "x"), "x") – russellpierce

+0

... tuttavia, trovo le funzioni Vectorized un po 'difficili da leggere, quindi preferisco la soluzione presentata nella mia risposta semplicemente perché è più facile per io (quando torno al codice) per capire come funziona. – russellpierce

Problemi correlati