2013-02-26 13 views
9

Ho bisogno di calcolare la media e la varianza di un sottoinsieme di un vettore. Sia x il vettore e sia un indicatore per stabilire se l'osservazione si trova nel sottoinsieme. Che è più efficiente:Il modo più efficace per sostituire i vettori

sub.mean <- mean(x[y]) 
sub.var <- var(x[y]) 

o

sub  <- x[y] 
sub.mean <- mean(sub) 
sub.var <- var(sub) 
sub  <- NULL 

Il primo approccio non crea un nuovo oggetto in modo esplicito; ma le chiamate a mean e var lo fanno implicitamente? O funzionano sul vettore originale come memorizzato?

Il secondo è più veloce perché non deve eseguire la sottosistema due volte?

Sono interessato alla velocità e alla gestione della memoria per i set di dati di grandi dimensioni.

+0

Se sei preoccupato di lavorare con set di dati veramente grandi, allora dovrai allontanarti da R (o fare un sacco di campionamenti). A parte questo, perché non valutare i due approcci? –

+7

@JackManey: Questo non è vero (o costruttivo), soprattutto perché non sai quanto siano grandi i set di dati "grandi" dell'utente. –

+2

@JackManey, Con i pacchetti 'ff' e 'ffbase' (e altri pacchetti "big data"), la pura open source R può essere abbastanza capace di gestire dataset di grandi dimensioni con efficienza e velocità. Ci sono anche prove da parte della gente di Revolutions Analytics che R può essere esteso per fornire prestazioni migliori del SAS per il lavoro glm "big data". R non è necessariamente un collo di bottiglia, anche se i pacchetti di base * si sbricioleranno sotto grandi dataset. – Dinre

risposta

7

Benchmarking su un vettore di lunghezza 10m indica che (sulla mia macchina) quest'ultimo approccio è più veloce:

f1 = function(x, y) { 
    sub.mean <- mean(x[y]) 
    sub.var <- var(x[y]) 
} 

f2 = function(x, y) { 
    sub  <- x[y] 
    sub.mean <- mean(sub) 
    sub.var <- var(sub) 
    sub  <- NULL 
} 

x = rnorm(10000000) 
y = rbinom(10000000, 1, .5) 

print(system.time(f1(x, y))) 
# user system elapsed 
# 0.403 0.037 0.440 
print(system.time(f2(x, y))) 
# user system elapsed 
# 0.233 0.002 0.235 

Questo non è sorprendere, mean(x[y])ha essere necessario creare un nuovo oggetto per la mean funzione su cui agire, anche se non lo aggiunge allo spazio dei nomi locale. Pertanto, f1 è più lento per dover eseguire il subset due volte (come ipotizzato).

+0

Il pacchetto microbenchmark è molto meglio per questo tipo di confronto: 'library (microbenchmark); microbenchmark (f1 (x, y), f2 (x, y)) ' – hadley

Problemi correlati