1

現在、日付 X より前の順序付けられたリストから最後の日付を返すものを作成しようとしています。

今、私はこれを持っています: それは日のリストを取得し、検索を行う日からインデックスを取得し、何日までに戻したいかの範囲を取得します。

その後、日付が存在するかどうかを確認します (例: 2 月 30 日)。日付が存在しない場合は、日付を 1 減らしてから再度フィルターを適用します (そうでない場合は、1 日を減算しようとしてNA失敗します)。

library(lubridate)
getDate <- function(dates,day,range){
    if(range == 'single')
        {return (day-1)}

    z <- switch(range,
        single = days(1),
        month = days(30),
        month3 = months(3),
        month6 = months(6),
        year = years(1)
        )

    new_day <-(dates[day]-z)
    i <- 1
    while (is.na(new_day)){
        new_day <- dates[day] - days(i) - z 
    }
    ind<-which.min(abs (diff <-(new_day-dates)))

    if (diff[ind] < 0)
    {ind <- ind -1}

    return (ind[1])
}

この機能は機能しますが、問題は速度効率です。which.min(abs())私は最速には程遠いと感じており、より良い代替手段があるかどうか疑問に思っています(リストを検索するための独自の関数を作成する以外に)。

stocks <- list(structure(list(sec = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), min = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), hour = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L), mday = c(2L, 3L, 4L, 7L, 8L, 9L, 10L, 11L, 14L, 15L, 16L, 17L,
18L, 22L, 23L, 24L, 25L, 28L, 29L, 30L, 31L, 1L, 4L, 5L, 6L), mon = c(0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L,
1L, 1L, 1L), year = c(108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L,
108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L, 108L,
108L, 108L, 108L), wday = c(3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L,
2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L), yday = c(1L, 2L, 3L, 6L, 7L,
8L, 9L, 10L, 13L, 14L, 15L, 16L, 17L, 21L, 22L, 23L, 24L, 27L, 28L, 29L, 30L,
31L, 34L, 35L, 36L), isdst = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("sec", "min",
"hour", "mday", "mon", "year", "wday", "yday", "isdst"), tzone = "UTC",
class = c("POSIXlt", "POSIXt")))

old_pos <- getDate(stocks[[1]],21,"month") #should return 0
old_pos <- getDate(stocks[[1]],22,"month") #should return 1

これはベクトルも日付も返さず、インデックスのみを返します。主な問題は、動作することではなく、最適化することです。

値は後で別の関数で使用されます。可能な速度向上の 1 つは、最初にすべての古いインデックスを新しいインデックスに一致させてから、それを別のリストとして返すことです。ただし、速度が向上するかどうかはわかりません。

4

2 に答える 2

3

sDateとを含む @agstudy の再定式化の使用x.Date

データ表

次のように data.table で計算を実行できます。最初の列は元の日付を示し、sDate2 番目の列は対応するx.Date日付です。

> library(data.table)
> data.table(date = x.Date, x.Date, key = "date")[J(sDate),, roll = TRUE]
         date     x.Date
1: 2003-02-03 2003-02-02
2: 2003-02-12 2003-02-10
3: 2003-02-16 2003-02-15

sqldf sqldfを使用すると、次のようになります。

> library(sqldf)
> sDateDF <- data.frame(sDate = sDate)
> xDateDF <- data.frame(xDate = x.Date)
> 
> sqldf("select s.sdate sDate, max(x.xdate) xDate 
+   from sDateDF s join xDateDF x on x.xDate <= s.sDate 
+   group by s.sDate")
       sDate      xDate
1 2003-02-03 2003-02-02
2 2003-02-12 2003-02-10
3 2003-02-16 2003-02-15

動物園

Zoo を使用して、2 つの Zoo シリーズを作成し、それらをマージして、このように na.locf を使用します。結果はx.Dateそれぞれに対応しますsDate(つまり、上記のソリューションのいずれかの 2 番目の列):

> library(zoo)
>
> zx <- zoo(seq_along(x.Date), x.Date)
> zs <- zoo(seq_along(sDate), sDate)
> x.Date[na.locf(merge(zx, zs))[sDate, "zx"]]
[1] "2003-02-02" "2003-02-10" "2003-02-15"
于 2013-06-21T15:18:35.533 に答える
2

たとえば、日付のベクトルがあることを理解していれば、次のようになります。

x.Date <- as.Date("2003-02-01") + c(1, 3, 7, 9, 14,20) 
"2003-02-02" "2003-02-04" "2003-02-08" "2003-02-10" "2003-02-15" "2003-02-21"

日付のベクトルを指定します。次に例を示します。

sDate <- as.Date("2003-02-01") + c(2,11,15)

x.Date でこの与えられた日付に近いが、この日付よりも前の日付を取得しようとします:

 lapply(sDate,function(x)max(x.Date[x.Date-x <=0]))
[[1]]
[1] "2003-02-02"

[[2]]
[1] "2003-02-10"

[[3]]
[1] "2003-02-15"
于 2013-06-21T14:57:44.060 に答える