2015-03-23 15 views
5

Penso di avere una domanda piuttosto semplice per R ma ho difficoltà a trovare un esempio. Dire che ho un vettore di numeriR: esecuzione di un calcolo su un vettore

practice<-c(1,2,10,15,17,1,2,4) 

e voglio calcolare la variazione tra i numeri. La lunghezza del vettore è fissata a 36 osservazioni. Esempio di ciò che voglio calcolare è ((2/1) -1), ((10/2-1), .... Sto pensando di costruire un ciclo for dove faccio riferimento alla posizione e ho un contatore associato a esso.

+3

Si prega di estrarre i loop maledetti dalla tua testa. Non li usiamo nel 99% delle volte in R. Semplicemente 'pratica [-1L]/pratica [-lunga (pratica)] - 1L' –

+0

Una domanda potresti definire cosa sia -1L. Definiresti la L sopra questa come la lunghezza del vettore o ha un significato specifico in R? – user3549613

+0

'1L' è uno lungo, ovvero 1 come un numero intero lungo. –

risposta

5

uno dei vantaggi di utilizzare R è la sua vectorization, il che significa che si può facilmente eseguire operazioni su un'intera vettore contemporaneamente anziché dover scorrere ogni elemento.

Come David Arenburg menzionato in un commento (con aggiornamenti grazie a BondedDust e Dominic Comtois), è possibile nel vostro caso fare questo:

practice[-1]/head(practice, -1) - 1 

Cosa fa questo

?

practice[-1] fa riferimento all'intero vettore tranne il primo elemento.

> practice[-1] 
[1] 2 10 15 17 1 2 4 

Analogamente, head(practice, -1) fa riferimento l'intero vettore tranne l'ultimo elemento.

> head(practice, -1) 
[1] 1 2 10 15 17 1 2 

Se si divide questi, otteniamo un vettore costituito da ciascun elemento del vettore originale diviso per l'elemento che precede. Possiamo suddividere questi vettori direttamente perché la divisione è un'operazione vettoriale.

> practice[-1]/head(practice, -1) 
[1] 2.0000 5.0000 1.5000 1.1333 0.0588 2.0000 2.0000 
> # ^ ^ ^ ^ ^ ^ ^
> # 2/1 10/2 15/10 17/15 1/17 2/1 4/2 

Come hai nel tuo esempio, siamo in grado di sottrarre 1 alla fine.

> practice[-1]/head(practice, -1) - 1 
[1] 1.0000 4.0000 0.5000 0.1333 -0.9412 1.0000 1.0000 

Questo viene applicato a ciascun elemento del vettore dal aggiunta è anche un'operazione vettorializzare in R.

n cicli necessari!

Il codice ciclo equivalente sarebbe questo:

x <- NULL 
for (i in 1:(length(practice) - 1)) { 
    x[i] <- practice[i + 1]/practice[i] - 1 
} 
x 
[1] 1.0000 4.0000 0.5000 0.1333 -0.9412 1.0000 1.0000 

Mentre che si ottiene anche ciò che si vuole, è ovviamente molto più a lungo. In effetti, in molti casi il codice loop equivalente è anche molto più lento, poiché i loop trasportano un sacco di bagaglio extra ad ogni iterazione. Quindi, oltre a semplificare il codice, la vettorizzazione contribuirà spesso a velocizzarlo.

+2

'tail (practice, -1)' è più compatto ed espressivo di 'practice [-lunga (pratica)]' –

+0

@BondedDust: Grazie per il suggerimento, lo apprezzo. Aggiornato la mia risposta. –

+2

In realtà 'tail (practice, -1)' ** equivale a ** 'practice [-1]'. Penso che tu intendessi 'head (practice, -1)' –

Problemi correlati