Search code examples
rxtszoo

Trying to sort an R xts object via the 'order' function


Can someone please help my understand why the 'order' function doesn't sort an xts data frame as expected? As you can see below, the order function appears to do its job since the indices appear sorted. However when this vector of indices is applied inside the MSFT xts object, the original order is maintained and no change in the order of the rows occurs. What am I missing? I realize that applying str(MSFT) reveals that the values are of type 'chr' but I don't think this should matter.

library(quantmod)
getSymbols("MSFT")

sorted_indices <- order(MSFT$MSFT.Adjusted)
sorted_indices
[1] 549 547 548 544 545 546

test <- MSFT[sorted_indices,]
head(test)
MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume
2007-01-03     29.91     30.25    29.40      29.86    76935100
2007-01-04     29.70     29.97    29.44      29.81    45774500
2007-01-05     29.63     29.75    29.45      29.64    44607200
2007-01-08     29.65     30.10    29.53      29.93    50220200
2007-01-09     30.00     30.18    29.73      29.96    44636600
2007-01-10     29.80     29.89    29.43      29.66    55017400
           MSFT.Adjusted
2007-01-03      21.96213
2007-01-04      21.92535
2007-01-05      21.80031
2007-01-08      22.01361
2007-01-09      22.03568
2007-01-10      21.81502

Solution

  • You can't change the ordering of a zoo object and since an xts object is a zoo object it applies to xts too. The oo in zoo stands for ordered observations. Such an object is always stored and shown in the order of its time index.

    You can create a matrix or data frame in various ways from the xts object like this in which case you could do anything that those objects allow.

    as.data.frame(MSFT) # data frame with times as row names
    coredata(zoo(MSFT)) # matrix with times as row names
    data.matrix(MSFT)   # matrix with times as row names
    fortify.zoo(MSFT)   # data frame with times in column 1
    coredata(MSFT)      # matrix.  No times.
    

    or this would create a zoo object whose times are 1, 2, 3, ... in the order of the adjusted column. The row names would be the associated dates.

    z <- zoo(MSFT, order(order(Ad(MSFT))))
    View(coredata(z))
    
    head(coredata(z))
    ##            MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume MSFT.Adjusted
    ## 2009-03-09     15.20     15.74    15.10      15.15    66479100      11.58155
    ## 2009-03-05     15.86     15.88    15.27      15.27    89708500      11.67328
    ## 2009-03-06     15.35     15.62    14.87      15.28    92821400      11.68093
    ## 2009-03-02     15.96     16.25    15.72      15.79    80602100      12.07080
    ## 2009-03-03     16.03     16.24    15.64      15.88    80476600      12.13960
    ## 2009-03-04     16.12     16.40    15.89      16.12    69285100      12.32307