Объединить два объекта xts (матрицы) в единый массив в R

#arrays #r #merge #xts

#массивы #r #объединить #xts

Вопрос:

У меня есть два объекта xts.

 > require(quantmod)

> getSymbols("GLD;SLV")
[1] "GLD" "SLV"

> head(SLV, n=2)
           SLV.Open SLV.High SLV.Low SLV.Close SLV.Volume SLV.Adjusted
2007-01-03   129.96   131.16  124.70    125.58    7480000        12.56
2007-01-04   126.04   127.97  125.45    125.80    3220000        12.58

> head(GLD, n=2)
           GLD.Open GLD.High GLD.Low GLD.Close GLD.Volume GLD.Adjusted
2007-01-03    63.58    64.02   62.00     62.28    8061900        62.28
2007-01-04    62.07    62.50   61.52     61.65    4858600        61.65

> NROW(SLV) == NROW(GLD)
[1] TRUE
  

Как вы можете «сложить» эти отдельные двумерные матрицы в единый трехмерный массив?

Что-то вроде следующего:

 metal <- xts_stacking_function (GLD, SLV)

class(metal)
[1] "array"

metal[1,,1]
              GLD.Open GLD.High GLD.Low GLD.Close GLD.Volume GLD.Adjusted
2007-01-03    63.58    64.02      62     62.28    8061900        62.28
  

Комментарии:

1. Во-первых, GLD и SLV — это не массивы, это объекты xts. Во-вторых, что вы подразумеваете здесь под 3D-массивом? Если вы хотите, чтобы они совместно использовали индекс, попробуйте newvar<-merge(SLV, GLD).

2. Можете ли вы привести пример желаемого результата?

3. @bill merge(SLV, GLD) вернет объект xts двух измерений, а не объект array, который я ищу.

4. @Milktrader: Обязательно ли это должен быть массив? Будет ли работать список объектов xts? Если вы немного подробнее опишете, что вы пытаетесь сделать, возможно, мы сможем создать решение.

5. @Джошуа, я рассматривал возможность использования списка объектов xts вместо массива и подумал, что, возможно, массив был бы проще, но я пересматриваю этот подход. Моя конечная цель — организовать большую группу перестановок торговой системы, каждая со своим торговым сигналом и доходностью, а затем легко выполнять вычисления по всему «пространству». Я еще немного подумаю над этим и, возможно, задам вопрос получше.

Ответ №1:

Я не думаю, что объекты xts поддерживают 3D-массивы. Вероятно, вам понадобится уродливое решение, подобное приведенному ниже. Помещение всего в массив приводит к приведению объектов к числовым значениям. Но, по крайней мере, это сохраняет индекс даты, хотя и в другом формате, поскольку массивы могут иметь только один тип данных.

 require(quantmod)
getSymbols("GLD;SLV")
GLD <- cbind(index(GLD), as.matrix(GLD))
SLV <- cbind(index(SLV), as.matrix(SLV))
C <- array(,c(dim(GLD),2))
C[,,1] <- GLD
C[,,2] <- SLV
  

Комментарии:

1. похоже, что дата удаляется, что важно для моих целей. Я добавлю больше кода выше, чтобы вы могли его дублировать, если хотите.

2. Смотрите мою правку. Боюсь, здесь не будет действительно чистого решения. Надеюсь, кто-нибудь другой сможет добавить что-нибудь получше.

3. Боюсь, вы можете быть правы, и нет способа создать массив из объектов xts. Я надеялся, что массивы смогут предоставить исключение из правила одного типа данных для объектов xts и zoo, потому что это именно то, что сделали матрицы. По сути, объект xts — это матрица, индексированная по времени, не так ли?

4. @Milktrader: да, объекты xts / zoo — это просто матрица с атрибутом «index».

Ответ №2:

Учитывая ваш последний комментарий, я думаю, вы могли бы сделать то, что хотите, одним из двух способов:

  1. использовать lapply со списком объектов xts
  2. использовать eapply с объектами xts, хранящимися в их собственной среде

Пример #2 с использованием getSymbols (обратите внимание, что eapply возвращает список):

 library(quantmod)
myEnv <- new.env()
getSymbols("GLD;SLV", env=myEnv)
eapply(myEnv, function(x) head(Cl(x),3))
# $SLV
#            SLV.Close
# 2007-01-03    125.58
# 2007-01-04    125.80
# 2007-01-05    121.80
# 
# $GLD
#            GLD.Close
# 2007-01-03     62.28
# 2007-01-04     61.65
# 2007-01-05     60.17