2016-12-13 16 views
3

私は、zoo/xtsのrollapplyなどの機能に似ていますが、私のニーズに適用できるコードを生成しようとしています。私はいくつかの非常に簡単なサンプルデータを使ってコードを作りました。しかし、今私はedhecデータで実行しようとしていますが、エラーが発生しています。なぜ私は不明ですが、それがifステートメントと関係があると仮定します。誰がエラーを受け取っているのかを診断できる人はいますか?ステートメントエラー/ステートメントが適用されない場合

#rm(list=ls()) #Clear environment 
cat("\014") #CTRL + L 

library(xts) 
library(lubridate) 

is.even <- function(x) x %% 2 == 0 

roundUp <- function(x,to=2) 
{ 
    to*(x%/%to + as.logical(x%%to)) 
} 

functionTest <- function(data, window, slide){ 

    nyears_t = nyears(data) 

    #IF statement for non-even numbers only 
    if(is.even(nyears_t == FALSE)) { 
    nyears_t <- roundUp(nyears_t) 
    data_extend <- data 

    start_extend <- .indexyear(data)[length(data)]+ 1900 + 1 
    end_extend <- start_extend + length(data) - 1 
    index(data_extend) <- update(index(data),year=start_extend:end_extend) 

    data <- rbind(data, data_extend) 

    warning("WARNING! The function has looped to the start of the timeseries. The final list(s) 
      will contain years that do not exist in the dataset. Please modify.") 
    } 

    nslides = nyears_t/slide 

    #Matrix 
    year_1 = (.indexyear(data)[1]+1900) 

    start <- seq(from = year_1, by = slide, length.out = nslides) 
    end <- start + window - 1 

    mat <- matrix(c(start, end), ncol = 2, dimnames = list(c(1:nslides), c("start", "end"))) 

    #For loop 
    subsetlist <- vector('list') 

    for(i in 1:nslides){ 
    subset <- data[paste0(mat[i,1], "/", mat[i,2])] 
    subsetlist[[i]] <- subset 
    } 
    print(subsetlist) 
} 

Iは、上記機能を行う時に使用したサンプルコード:

a <- seq(from = as.POSIXct("2000", format = "%Y"), to = as.POSIXct("2008", format = "%Y"), by = "year") 
a <- as.xts(1:length(a), order.by = a) 
a 

functionTest(data = a, window = 3, slide = 2) 

私がテストとエラーを受信して​​いますサンプルコード:

> data(edhec, package = "PerformanceAnalytics") 
> edhec <- edhec[,1:3] 
> edhec <- edhec["/2007"] 
> head(edhec) 
      Convertible Arbitrage CTA Global Distressed Securities 
1997-01-31    0.0119  0.0393    0.0178 
1997-02-28    0..0298    0.0122 
1997-03-31    0.0078 -0.0021    -0.0012 
1997-04-30    0.0086 -0.0170    0.0030 
1997-05-31    0.0156 -0.0015    0.0233 
1997-06-30    0.0212  0.0085    0.0217 
> functionTest(data = edhec, window = 3, slide = 2) 
Show Traceback 

Rerun with Debug 
Error in start_extend:end_extend : NA/NaN argument 
> 

UPDATE:

コードが次のアップデートで実行されるようになりましたifステートメント(Joshua Ulrichのおかげで)(下記のコードを参照)。しかし、if文にはまだ問題があります。データセットに偶数年または奇数年があるかどうかにかかわらず実行されるように見えます。これは関数の精度には影響しませんが、大きなデータセットを考慮すると問題になることがあります。もし誰かがこれに関する考えを持っていれば、それは大いに感謝されるでしょう。さもなければこれは既に超大です! (XTS /動物園オブジェクトのcoredataが何であるかである)マトリックス上lengthを呼び出す歓声

if(is.even(nyears_t == FALSE)) { 
    nyears_t <- roundUp(nyears_t) 
    data_extend <- data 

    start_extend <- .indexyear(data)[nrow(data)] + 1900 + 1 
    end_extend <- start_extend + nyears(data) - 1 

    dates <- index(data) 
    tmp <- as.POSIXlt(dates) 
    tmp$year <- tmp$year + nyears(data) 
    dates2 <- as.POSIXct(tmp, tz = tz) 
    index(data_extend) <- dates2 

    data <- rbind(data, data_extend) 

    warning("WARNING! The function has looped to the start of the timeseries. The final list(s) 
      will contain years that do not exist in the dataset. Please modify.") 
    } 

答えて

2

はあなたの要素の総数(基礎となるベクターの、すなわち長さ)を与えます。代わりにnrowを使用してください。

start_extend <- .indexyear(data)[nrow(data)] + 1900 + 1 
end_extend <- start_extend + nrow(data) - 1 

あなたはdataが、あなたはNROW代わりのnrowを使用する必要があり、行列またはベクトルになるかどうかわからない場合。ベクトル上にnrowを呼び出すとNULLNROWが返され、xがベクトルの場合はlength(x)が返されます。

+0

ありがとうございました@ジョシュア、私はこのエラーを自分で見つけました。私はこの機能を使いこなしていました。また、コードを正しく実行するためには、いくつかの変更が必要であることに気付きました(質問に追加しました)。 これで、意図したとおりにコードが実行されているようです。しかし、まだまだ小さな悩みがあります。 if文が常に実行中のようです...私はedhecを奇数と偶数に変更し、if文は常に適用されます。これは、if文の中に根本的に何かが間違っていることを示唆しています。 – Visser

+0

@ Visser:あなたのアップデートに関しては、あなたは 'if(!is。偶数(nyears_t)) 'である。 –

0

私は今、望ましい効果がある完全な答えを考え出しました。助けてくれてありがとう@ジョシュア - 私はそれなしでコードを修正できたとは思わない。大きなデータでそれを実行するために、私はいくつかの追加の変更を加えなければなりませんでした。

関心のために、これは私の完全な作業コード(マイナス私の追加のカスタム関数)である:

bootOffset <- function(data, window, slide, tz = "GMT"){ 

    nyears_t = nyears(data) 

    #IF statement for non-even numbers only 
    if(is.even(nyears_t) == FALSE) { 
    nyears_t <- roundUp(nyears_t) 
    data_extend <- data 

    start_extend <- .indexyear(data)[nrow(data)] + 1900 + 1 
    end_extend <- start_extend + nyears(data) - 1 

    dates <- index(data) 
     tmp <- as.POSIXlt(dates); tmp$year <- tmp$year + nyears(data) 
    dates2 <- as.POSIXct(tmp, tz = tz) 

    index(data_extend) <- dates2 
    data <- rbind(data, data_extend) 
    } 

    nslides = nyears_t/slide 

    year_1 = (.indexyear(data)[1] + 1900) 

    #Matrix 
    start <- seq(from = year_1, by = slide, length.out = nslides); end <- start + window - 1 
    mat <- matrix(c(start, end), ncol = 2, dimnames = list(c(1:nslides), c("start", "end"))) 

    #For loop 
    subsetlist <- vector('list') 

    for(i in 1:nslides){ 
    subset <- window(data, 
        start = as.POSIXct(paste0(mat[i,1], "-01-01")), 
        end = as.POSIXct(paste0(mat[i,2], "-12-31"))) 

    subsetlist[[i]] <- subset 
    } 
    print(subsetlist) 
} 

し、必要に応じて、これらの結果が出てくることの確認のために:

data(edhec, package = "PerformanceAnalytics") 
edhec <- edhec[,1:3] 
edhec08 <- edhec["/2008"] 
edhec07 <- edhec["/2007"] 

bootOffset(data = edhec08, #EVEN 
        window = 4, 
        slide = 3) 

bootOffset(data = edhec07, #ODD 
        window = 4, 
        slide = 3) 
> bootOffset.Check <- function(boot){ 
+ dates <- lapply(boot, year) 
+ dates <- lapply(dates, unique) 
+ dates <- lapply(dates, `length<-`, max(lengths(dates))) 
+ as.data.frame(dates, 
+ col.names = paste0("boot_", 1:length(boot))) 
+ 
+ } 
> 
> nyears(edhec08) 
[1] 12 
> bootOffset.Check(boot08) #EVEN number of years 
    boot_1 boot_2 boot_3 boot_4 
1 1997 2000 2003 2006 
2 1998 2001 2004 2007 
3 1999 2002 2005 2008 
4 2000 2003 2006  NA 
> 
> nyears(edhec07) 
[1] 11 
> bootOffset.Check(boot07) #ODD number of years 
    boot_1 boot_2 boot_3 boot_4 
1 1997 2000 2003 2006 
2 1998 2001 2004 2007 
3 1999 2002 2005 2008 
4 2000 2003 2006 2009 
> 
関連する問題