2010-11-30 3 views
2

У меня есть следующая проблема:Применить ksmooth временных рядов

У меня есть кадр данных «тест», который выглядит более или менее, как это:

Date   return  price  vol 
20100902  0.3  15   8.5 
20100902  0.4  17   8.6 
20100902  0.6  19   8.7 
..... 
20100903  0.2  13   8.2 
20100903  0.4  17   8.6 
20100903  0.8  21   9.0 
..... 

Так я заданные значения для каждой даты (10 в день). Теперь я хотел бы применить ksmooth() для каждой даты, например, ksmooth (return, price, n.points = 50) для каждой даты. Это должно дать мне 50 наблюдений за каждую дату. Кроме того, мне нужна отметка времени для интерполированных значений. Таким образом, результирующая рама должна соответствовать

Date   return  price   
20100620  0.3  15 
20100620  0.31  15.2 
20100620  0.32  15.3 
20100620  0.4  17   
20100620  0.6  19   
..... 
20100621  0.2  13  
20100621  0.21  13.1 
20100621  0.22  13.2 
20100621  0.4  17   
20100621  0.8  21  
etc. 

с 50 наблюдениями в день. Итак, вот что я ищу: возьмите первые 10 наблюдений (например, дата 1 = 20102006, интерполируйте и поместите отметку времени на интерполированные значения (20100620). Затем возьмите второе 10 наблюдений (date = 20100621), выполните интерполяцию и поставьте отметку времени на интерполированные значения (20100621) и т. д.

Я новичок в R, но это то, что я пробовал. Я думал об использовании функции zoo(). Я хотел, чтобы моя дата записей уникальна, так что я просто добавил час к каждой записи

test <- read.zoo("test.txt", format = "%Y%m%d") 
test <- zoo(test, as.POSIXct(time(test)) + 1:26) 

Там, вероятно, что-то не так с этим, потому что R жаловался. Тогда я думал использовать Ролл pply().

roll.test <- rollapply(test, 10, FUN = function(x,y) ksmooth(test$return,  
+ test$price, "normal", bandwidth = 20, n.points = 50)) 

К сожалению, результат очень сбивает с толку. И запрос by.column = FALSE не работает.

Я очень благодарен за помощь. Он не должен основываться на моей «пробной версии» вообще. Большое спасибо Дани

Мои данные выглядит следующим образом:

"date" "days" "return" "price" 
"66" 20100620 91 0.18 1389.373 
"67" 20100620 91 0.19 1370.57 
"68" 20100620 91 0.19 1353.122 
"69" 20100620 91 0.19 1336.291 
"70" 20100620 91 0.20 1319.774 
"71" 20100620 91 0.20 1303.341 
"72" 20100620 91 0.21 1286.656 
"326" 20100621 91 0.18 1386.28 
"327" 20100621 91 0.18 1367.694 
"328" 20100621 91 0.19 1350.375 
"329" 20100621 91 0.19 1333.615 
"330" 20100621 91 0.20 1317.164 
"331" 20100621 91 0.20 1300.783 
"332" 20100621 91 0.21 1284.113 
+0

это всегда хорошая идея, чтобы обеспечить игрушечный набор данных, чтобы проверить код. Поскольку у нас нет теста.txt, трудно сказать, почему R жалуется. – 2010-11-30 12:37:42

+0

вы можете проверить функцию `dput()`. Если вы дадите этот вывод, мы просто можем скопировать его в R и иметь точно такой же объект. Или, наоборот, сделайте так, как я сделал в своем решении, чтобы убедиться, что нам просто нужно скопировать код и получить объект. – 2010-11-30 13:26:01

ответ

5

Проблема заключается в том, что функция ksmooth будет возвращать список, и эти списки будут сохранены как на rollaplly. Кстати, я не думаю, что вы даже хотите использовать rollaplly, поскольку это не делает этого для каждой даты, но «перекатывается» над файловым кадром. Я верю из вашего объяснения, что это не желаемое поведение.

Я не мог по-настоящему разобраться, используя объект зоопарка, так как он довольно ограничительный. Может быть, кто-то еще покажет вам это. Вы можете построить эту dataframe с помощью функции ddply из plyr пакета:

tt <- ddply(test,.(Date), 
    function(x) { 
     as.data.frame(ksmooth(x$return,x$price,"normal",bandwidth=2,n.points=50)) 
    }) 

тт может быть преобразован в объект зоопарка, используя

tt2 <- zoo(tt, as.POSIXct(tt$Date) + 1:50) 

В качестве альтернативы, вы можете сделать это вручную, используя немного манипулирования списками. снова полученное tt может быть преобразовано по линии выше в объект зоопарка.

tt <- split(test,test$Date) 

tt <- lapply(tt,function(x){ 
     as.data.frame(ksmooth(x$return,x$price,"normal",bandwidth=2,n.points=50)) 
     }) 

tt <- do.call(rbind,tt) 
names(tt) <- c("return","price") 
tt$Date <- as.Date(gsub("\\.\\d+","",rownames(tt))) 

Имейте в виду, я использовал read.table() построить тест:

zz <- textConnection(
"Date ,  return , price , vol 
20100902 , 0.3 ,  15 ,  8.5 
20100902 , 0.4 ,  17 ,  8.6 
20100902 , 0.6 ,  19 ,  8.7 
20100903 , 0.2 ,  13 ,  8.2 
20100903 , 0.4 ,  17 ,  8.6 
20100903 , 0.8 ,  21 ,  9.0" 
) 
test <- read.table(zz,header=T,sep=",") 
test$Date <- as.Date(as.character(test$Date),format="%Y%m%d") 
close(zz) 
Смежные вопросы