Слияние ценовых временных рядов в xts, когда ценные бумаги не показывают данных

Я запрашиваю базу данных безопасности. Ценовые ряды указаны в xts, а для некоторых могут отсутствовать данные (для выбранного окна). Фактические временные ряды можно смоделировать следующим образом:

require(xts)

## Simulated time series
price=function(){
    x=floor(runif(1,1,4))
    xts(round(rnorm(x,5),3), Sys.Date()+1:x)    
}
## Sample tickers
(tick1=setNames(price(), "tick1"))
#            tick1
# 2014-04-20 5.829
# 2014-04-21 6.061
# 2014-04-22 5.813
(tick2=setNames(price(), "tick2"))
#            tick2
# 2014-04-20 6.458
# 2014-04-21 5.373
(tick3=xts(data.frame(tick3=numeric()), as.Date(numeric()))) # Security showing no data
#            tick3
## ...
## tickn

Не нужно упоминать, что я не знаю заранее, какая безопасность не покажет никаких данных.

Если я объединим цены в один объект xts, merge.xts полностью удалит из вывода пустые ценные бумаги:

(port=merge(tick1, tick2, tick3))
#            tick1 tick2
# 2014-04-20 5.829 6.458
# 2014-04-21 6.061 5.373
# 2014-04-22 5.813    NA

Вместо этого я хотел бы отслеживать их, поэтому напечатайте вывод, похожий на:

(cbind(port, tick3=NA))
#            tick1 tick2 tick3
# 2014-04-20 5.829 6.458    NA
# 2014-04-21 6.061 5.373    NA
# 2014-04-22 5.813    NA    NA

Одно из возможных решений:

port=list(tick1, tick2, tick3) # ... tickn
port.m=lapply(port, function(sec){
    if(nrow(sec)==0) sec= xts(matrix(NA, dimnames=dimnames(tick3)), Sys.Date())
    sec
})
(port.m=do.call('merge', port.m))
#            tick1 tick2 tick3
# 2014-04-19    NA    NA    NA
# 2014-04-20 5.829 6.458    NA
# 2014-04-21 6.061 5.373    NA
# 2014-04-22 5.813    NA    NA
if(all(is.na(port.m[Sys.Date()])))
    (port.m=port.m[time(port.m)!=Sys.Date()])
#            tick1 tick2 tick3
# 2014-04-20 5.829 6.458    NA
# 2014-04-21 6.061 5.373    NA
# 2014-04-22 5.813    NA    NA

Можно ли найти более разумное решение?


person antonio    schedule 18.04.2014    source источник
comment
merge.xts не удаляет пустые ценные бумаги. tick3 — это не просто отсутствующие данные; он имеет индекс нулевой длины, поэтому объединять нечего. У меня отсутствуют данные для некоторых дат, которые отличаются от того, что у меня нет дат. Это также согласуется с merge.zoo. Почему бы не просто: if(nrow(sec)==0) sec=NA?   -  person Joshua Ulrich    schedule 20.04.2014


Ответы (1)


Здесь вы делаете две ошибки: во-первых: вам нужно использовать вектор ненулевой длины. Видеть это:

length(integer())
length(NA)

Во-вторых: чтобы слияние работало, индексы объектов xts должны где-то совпадать.

например что-то вроде этого будет работать:

require(xts)
x=xts(1:4, Sys.Date()+1:4)
v=xts(NA, Sys.Date()+1) 
(m=merge.xts(x,v))

Здесь начальный индекс совпадает, а остальные индексы заполняются.

Если вы хотите быть очень конкретным, вы, вероятно, могли бы попробовать что-то вроде этого:

v=xts(rep(NA,4), Sys.Date()+1:4)

Надеюсь это поможет!!

person Shambho    schedule 18.04.2014
comment
+1, но небольшая поправка: индексы не должны перекрываться. Например: merge(x=.xts(1,1),y=.xts(1,2)). - person Joshua Ulrich; 19.04.2014
comment
Ваш ответ не по теме. Как я уже писал, мне нужно работать с этими данными. Я не могу просить провайдера (биржу) сделать его таким, чтобы он подходил под мои нужды. Если бы в объектах void xts были NA, я бы не писал здесь. Кстати, из маркетинговых соображений я переформулировал вопрос в финансовом плане (чтобы привлечь более широкую аудиторию), а также предложил скучное, но работающее решение. - person antonio; 19.04.2014
comment
Чувак ... ты полностью отредактировал исходный вопрос ... Я отвечал на твой исходный вопрос. Не тот что у тебя сейчас!! В любом случае... С наилучшими пожеланиями! - person Shambho; 20.04.2014