2011-11-23 148 views
3

我有一個時間索引矩陣(xts對象),我只想每個十一月的第四個星期三。獲取每個11月的第四個星期三R

require(quantmod) 
getSymbols("^GSPC", from="1900-01-01") #returns GSPC 
GSPC$WED <- weekdays(time(GSPC)) == "Wednesday" 
GSPC$NOV <- months(time(GSPC)) == "November" 
G   <- GSPC[GSPC$WED==1 & GSPC$NOV==1] 

這就像我在R得到解決我的問題,我踢了bash。

write.zoo(G, "wen_in_nov") 

我做了下面的技巧:

cat wen_in_nov | 
grep -v IND | 
cut -c 1-10 | 
sed 's/-/ /g' | 
awk '{if($3 >= 22 && $3 < 29) print $1, $2, $3, "winner"}' | 
sed 's/ /-/g' > fourth_wen 

fourth_wen文件需要從字符串「贏家」的-分開,所以我只是在vi這樣做。導入到回R:

fourth_wen <- read.zoo("fourth_wen", format="%Y-%m-%d") 

而且基本上是第四個星期三在十一月自1950年以來有沒有辦法用更少的代碼做這一切R中?

+0

能否請您介紹如何貴wen_in_nov樣子? –

+0

Jaypal,你可以將上面的第6行拷貝到R中,並且你應該在工作目錄中有文件(當然你需要安裝'quantmod') – Milktrader

回答

5

使用.indexmon等訪問POSIXlt值直接

GSPC[.indexmon(GSPC)==10 & .indexmday(GSPC) > 22 & .indexmday(GSPC) < 29 
     &.indexwday(GSPC) == 3] 

      GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted 
2007-11-28 1432.95 1471.62 1432.95 1469.02 4508020000  1469.02 
2008-11-26 852.90 887.68 841.37  887.68 5793260000  887.68 
2009-11-25 1106.49 1111.18 1104.75 1110.63 3036350000  1110.63 
2010-11-24 1183.70 1198.62 1183.70 1198.35 3384250000  1198.35 
2011-11-23 1187.48 1187.48 1161.79 1161.79 3798940000  1161.79 
+0

不錯。通過去bashscript和後面讓我不會犯錯誤。 – Milktrader

+0

最終用戶將不得不記住它使用相同的容易出錯的POSIX規範,這個規範的編號從0到11的月份不是很友好。 –

+0

你的表達錯過了1961年,1967年,1972年,1978年,1989年,1995年和2006年;看到我編輯的答案。 –

2

這裏有一種方法

nov_dates <- expand.grid(1:30, 11, 1900:2011) 
nov_dates <- apply(nov_dates, 1, paste, collapse = "-") 
nov_dates <- dmy(nov_dates) 
nov_wed <- nov_dates[wday(nov_dates, label = TRUE) == 'Wed'] 
nov_4wed <- nov_wed[seq_along(nov_wed) %% 4 == 0] 

編輯。一個小錯誤依然存在。如果11月份有5個星期三,這段代碼不起作用。一個小小的改正會照顧它,我會很快發佈它。下面是正常工作

library(plyr) 
library(lubridate) 
nov_dates <- expand.grid(day = 1:30, month = 11, year = 1900:2011) 
nov_dates <- transform(nov_dates, 
    date = dmy(paste(day, month, year, sep = "-")) 

nov_4_wed <- ddply(nov_dates, .(year), summarize, date[wday(date) == 4][4]) 
1

我不花大量的時間與時間序列對象,所以有可能是一個更好的功能比使用substr提取天(實際上是一個解決方案,我敢肯定有,我只是不知道它從我的頭頂上)。但這似乎工作:

rs <- subset(GSPC,weekdays(time(GSPC)) == "Wednesday" & 
        months(time(GSPC)) == "November" & 
        as.numeric(substr(time(GSPC),9,10)) >= 22 & 
        as.numeric(substr(time(GSPC),9,10)) < 29) 
3

我的RcppBDT包有這個功能。

RcppBDT包裝部分Boost Date_Time庫和Boost Date_Time碰巧有這樣的功能。因此,這裏是一個快速循環的年份2008至2011年,讓每年的第四個星期三在十一月:

R> library(RcppBDT) 
Loading required package: Rcpp 
Creating a generic function for ‘print’ from package ‘base’ in package ‘RcppBDT’ 
Creating a generic function for ‘format’ from package ‘base’ in package ‘RcppBDT’ 
R> for (y in 2008:2011) print(getNthDayOfWeek(fourth, Wed, Nov, y)) 
[1] "2008-11-26" 
[1] "2009-11-25" 
[1] "2010-11-24" 
[1] "2011-11-23" 
R> 

這裏fourthWedNov是在包命名空間常量,在底層C對應的enum類型仿照++庫。使用非常簡單。

編輯:下面是一個完整的例子全部4日,星期三,在 - 11月自2000年以來我保證,無論週三的GSPC和矢量Wed同意同Date類型。然後,它僅僅是一個堅持WedGSPC的事情:

R> library(quantmod) 
Loading required package: Defaults 
Loading required package: TTR 
R> getSymbols("^GSPC", from="1900-01-01") 
R> Wed <- sapply(2000:2011, function(y) getNthDayOfWeek(fourth, Wed, Nov, y)) 
R> index(GSPC) <- as.Date(index(GSPC)) 
R> GSPC[as.Date(Wed)] 
      GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted 
2000-11-22 1347.35 1347.35 1321.89 1322.36 963200000  1322.36 
2001-11-28 1149.50 1149.50 1128.29 1128.52 1423700000  1128.52 
2002-11-27 913.31 940.41 913.31  938.87 1350300000  938.87 
2003-11-26 1053.89 1058.45 1048.28 1058.45 1097700000  1058.45 
2004-11-24 1176.94 1182.46 1176.94 1181.76 1149600000  1181.76 
2005-11-23 1261.23 1270.64 1259.51 1265.61 1985400000  1265.61 
2006-11-22 1402.69 1407.89 1402.26 1406.09 2237710000  1406.09 
2007-11-28 1432.95 1471.62 1432.95 1469.02 4508020000  1469.02 
2008-11-26 852.90 887.68 841.37  887.68 5793260000  887.68 
2009-11-25 1106.49 1111.18 1104.75 1110.63 3036350000  1110.63 
2010-11-24 1183.70 1198.62 1183.70 1198.35 3384250000  1198.35 
2011-11-23 1187.48 1187.48 1161.79 1161.79 3798940000  1161.79 
R> 

編輯2作爲公共Servive公告,這裏是Jeff的答案失敗:

R> ind <- .indexmon(GSPC)==10 & .indexmday(GSPC) > 22 & .indexmday(GSPC) < 29 
+   & .indexwday(GSPC) == 3 
R> index(GSPC)[ind] 
[1] "1951-11-28" "1952-11-26" "1953-11-25" "1954-11-24" "1955-11-23" 
[6] "1956-11-28" "1957-11-27" "1958-11-26" "1959-11-25" "1960-11-23" 
[11] "1962-11-28" "1963-11-27" "1964-11-25" "1965-11-24" "1966-11-23" 
[16] "1968-11-27" "1969-11-26" "1970-11-25" "1971-11-24" "1973-11-28" 
[21] "1974-11-27" "1975-11-26" "1976-11-24" "1977-11-23" "1979-11-28" 
[26] "1980-11-26" "1981-11-25" "1982-11-24" "1983-11-23" "1984-11-28" 
[31] "1985-11-27" "1986-11-26" "1987-11-25" "1988-11-23" "1990-11-28" 
[36] "1991-11-27" "1992-11-25" "1993-11-24" "1994-11-23" "1996-11-27" 
[41] "1997-11-26" "1998-11-25" "1999-11-24" "2001-11-28" "2002-11-27" 
[46] "2003-11-26" "2004-11-24" "2005-11-23" "2007-11-28" "2008-11-26" 
[51] "2009-11-25" "2010-11-24" "2011-11-23" 

R> S <- 1951:2011 
R> S[!S %in% as.numeric(format(index(GSPC)[ind], "%Y")) ] 
[1] 1961 1967 1972 1978 1989 1995 2000 2006 
R> 

因此,當你使用他的方法時,在六十個樣本中缺少八年。

+0

真棒!那麼這個軟件包是否會對日期進行自然語言處理? – Ramnath

+0

不,我已經提到'第一','第二',...只是常數1,2,3和3。鍵入「4th,Wed,Nov」比「4,3,11」更容易,但這最終會傳遞給C++代碼。但即使在C++中,您也可以將所有API函數與「4th,Wed,Nov」一起使用,因爲它們是適當的Boost命名空間中的枚舉。它只是*一個非常聰明的技巧,不需要NLP ;-) –

+0

我正在重新安裝Boost來試試這個。 (以爲我已經安裝了它) – Milktrader

相關問題