2012-03-01 5 views
9

Voglio eseguire una funzione su tutti i periodi di una matrice xts. applicare() è molto veloce, ma la matrice restituita ha recepito le dimensioni rispetto all'oggetto originale:Perché apply() restituisce una matrice xts trasposta?

> dim(myxts) 
[1] 7429 48 
> myxts.2 = apply(myxts, 1 , function(x) { return(x) }) 
> dim(myxts.2) 
[1] 48 7429 
> str(myxts) 
An 'xts' object from 2012-01-03 09:30:00 to 2012-01-30 16:00:00 containing: 
    Data: num [1:7429, 1:48] 4092500 4098500 4091500 4090300 4095200 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : NULL 
    ..$ : chr [1:48] "Open" "High" "Low" "Close" ... 
    Indexed by objects of class: [POSIXlt,POSIXt] TZ: 
    xts Attributes: 
NULL 
> str(myxts.2) 
num [1:48, 1:7429] 4092500 4098500 4091100 4098500 0 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : chr [1:48] "Open" "High" "Low" "Close" ... 
    ..$ : chr [1:7429] "2012-01-03 09:30:00" "2012-01-03 09:31:00" "2012-01-03 09:32:00" "2012-01-03 09:33:00" ... 
> nrow(myxts) 
[1] 7429 
> head(myxts) 
         Open High  Low Close 
2012-01-03 09:30:00 4092500 4098500 4091100 4098500 
2012-01-03 09:31:00 4098500 4099500 4092000 4092000 
2012-01-03 09:32:00 4091500 4095000 4090000 4090200 
2012-01-03 09:33:00 4090300 4096400 4090300 4094900 
2012-01-03 09:34:00 4095200 4100000 4095200 4099900 
2012-01-03 09:35:00 4100000 4100000 4096500 4097500 

Come posso conservare myxts dimensioni?

+1

Un piccolo frammento di dati sarebbe utile per ricreare il problema. – Justin

risposta

15

Questo è ciò che è documentato da apply. Da ?apply:

Valore:

If each call to ‘FUN’ returns a vector of length ‘n’, then ‘apply’ 
returns an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n > 1’. 

Nel tuo caso, 'n'=48 (perché si sta looping sopra le righe), in modo apply restituirà un array di dimensioni c(48, 7429).

Si noti inoltre che myxts.2 è non un oggetto xts. È un array normale. Hai un paio di opzioni:

  1. trasporre i risultati di apply prima di ri-creare i XTS obiettare:

    data(sample_matrix) 
    myxts <- as.xts(sample_matrix) 
    dim(myxts) # [1] 180 4 
    myxts.2 <- apply(myxts, 1 , identity) 
    dim(myxts.2) # [1] 4 180 
    myxts.2 <- xts(t(apply(myxts, 1 , identity)), index(myxts)) 
    dim(myxts.2) # [1] 180 4 
    
  2. Vectorize la funzione in modo che opera su tutte le righe di un XTS oggetto e restituisce un oggetto xts. Quindi non devi preoccuparti di su apply.

Infine, si prega di iniziare a fornire esempi riproducibili. Non è così difficile e rende molto più facile per le persone aiutare. Ho fornito un esempio sopra e spero che tu possa usarlo nelle tue domande seguenti.

+0

Se voglio andare per l'opzione 2, come posso passare ogni riga completa alla mia funzione di elaborazione? Ad esempio, myxts $ result = myxts $ Close - myxts $ Open funziona per campi specifici, ma cosa succede se voglio chiamare una funzione che passa nella riga completa come uno dei parametri? –

+1

@RobertKubrick: Non posso rispondere a questo senza vedere la tua funzione. Potrebbe essere o non essere possibile. Come minimo, potresti avvolgere la tua funzione di elaborazione in un'altra funzione che fa l'opzione 1. Non sarà veramente vettorializzata, ma sarà più pulita se la farai molto. –

+0

La soluzione 1 è molto veloce rispetto a un ciclo for. Vorrebbe capire perché, ma forse questa è una domanda diversa. –