2017-05-01 26 views
0

這裏我的時間範圍:創建10,000假多年日期data.frames基於365天窗口

start_day = as.Date('1974-01-01', format = '%Y-%m-%d') 
end_day = as.Date('2014-12-21', format = '%Y-%m-%d') 

df = as.data.frame(seq(from = start_day, to = end_day, by = 'day')) 
colnames(df) = 'date' 

我需要創建萬個data.frames用不同的假多年的365天每一個。這意味着10,000個數據框中的每一個都需要有不同的開始和結束年份。

總計df已經到達14,965天,其中365天= 41年。換句話說,df需要分組10,000次不同 41年(每個365天)。 每年的開始必須是隨機的,所以它可以是1974-10-03,1974-08-30,1976-01-03等等,並且末尾df的剩餘日期需要被回收開始的一個。

分組的假年需要出現在data.frames的第三列中。

我會把所有的data.frames放到一個列表中,但我不知道如何創建生成10,000個不同年份的開始日期的函數,然後將每個data.frame與365天的窗口分組41次。

任何人都可以幫助我嗎?


@gringer給了一個很好的答案,但它只能解決90%的問題:

dates.df <- data.frame(replicate(10000, seq(sample(df$date, 1), 
              length.out=365, by="day"), 
           simplify=FALSE)) 
colnames(dates.df) <- 1:10000 

我需要爲10,000列與日期由14965行從df採取哪些需要是最終在達到df的末尾時回收。

我試圖更改length.out = 14965但R不回收​​日期。


另一種選擇可能是改變length.out = 1,並最終通過保持相同的順序添加其餘df排爲每列

dates.df <- data.frame(replicate(10000, seq(sample(df$date, 1), 
              length.out=1, by="day"), 
           simplify=FALSE)) 
colnames(dates.df) <- 1:10000 

我怎樣才能加入剩餘的df行到每個col?

+1

也許'樣品(DF $日,10000)'可以幫助您獲得10000個不同的隨機的開始日期? – coffeinjunky

回答

3

seq方法也適用如果to參數是未指定的,所以它可以被用於產生起始於一個特定日期的特定天數:

> seq(from=df$date[20], length.out=10, by="day") 
[1] "1974-01-20" "1974-01-21" "1974-01-22" "1974-01-23" "1974-01-24" 
[6] "1974-01-25" "1974-01-26" "1974-01-27" "1974-01-28" "1974-01-29" 

當結合replicatesample使用我想這會給你一個列表想要什麼:

> replicate(2,seq(sample(df$date, 1), length.out=10, by="day"), simplify=FALSE) 
[[1]] 
[1] "1985-07-24" "1985-07-25" "1985-07-26" "1985-07-27" "1985-07-28" 
[6] "1985-07-29" "1985-07-30" "1985-07-31" "1985-08-01" "1985-08-02" 

[[2]] 
[1] "2012-10-13" "2012-10-14" "2012-10-15" "2012-10-16" "2012-10-17" 
[6] "2012-10-18" "2012-10-19" "2012-10-20" "2012-10-21" "2012-10-22" 

沒有simplify=FALSE說法,它產生一個整數數組(即,R的INTE日期的表示),這有點複雜的轉換回日期。一個稍微更復雜的方式來做到這一點,併產生日期輸出是使用data.frame上的非簡化replicate結果。這裏是一個將在每列產生365個日期10,000列數據幀的例子(大約需要5秒生成我的電腦上):

dates.df <- data.frame(replicate(10000, seq(sample(df$date, 1), 
              length.out=365, by="day"), 
           simplify=FALSE)); 
colnames(dates.df) <- 1:10000; 
> dates.df[1:5,1:5]; 
      1   2   3   4   5 
1 1988-09-06 1996-05-30 1987-07-09 1974-01-15 1992-03-07 
2 1988-09-07 1996-05-31 1987-07-10 1974-01-16 1992-03-08 
3 1988-09-08 1996-06-01 1987-07-11 1974-01-17 1992-03-09 
4 1988-09-09 1996-06-02 1987-07-12 1974-01-18 1992-03-10 
5 1988-09-10 1996-06-03 1987-07-13 1974-01-19 1992-03-11 

來獲得日期環繞工作,稍微修改以便能夠對原始數據幀,在末尾粘貼自己的副本:

df <- as.data.frame(c(seq(from = start_day, to = end_day, by = 'day'), 
         seq(from = start_day, to = end_day, by = 'day'))); 
colnames(df) <- "date"; 

這樣更容易編碼下游;替代是用於與用於開始/結束的附加計算和if語句每個結果列處理邊界的情況下雙seq

現在不是做日期計算,結果列從原始數據幀(其中算術已經完成)的子集。從幀的前半部分的一個日期開始,然後選擇下一個14965值。我使用nrow(df)/2,而不是一個更通用代碼:

dates.df <- 
    as.data.frame(lapply(sample.int(nrow(df)/2, 10000), 
         function(startPos){ 
          df$date[startPos:(startPos+nrow(df)/2-1)]; 
         })); 
colnames(dates.df) <- 1:10000; 

>dates.df[c(1:5,(nrow(dates.df)-5):nrow(dates.df)),1:5]; 
       1   2   3   4   5 
1  1988-10-21 1999-10-18 2009-04-06 2009-01-08 1988-12-28 
2  1988-10-22 1999-10-19 2009-04-07 2009-01-09 1988-12-29 
3  1988-10-23 1999-10-20 2009-04-08 2009-01-10 1988-12-30 
4  1988-10-24 1999-10-21 2009-04-09 2009-01-11 1988-12-31 
5  1988-10-25 1999-10-22 2009-04-10 2009-01-12 1989-01-01 
14960 1988-10-15 1999-10-12 2009-03-31 2009-01-02 1988-12-22 
14961 1988-10-16 1999-10-13 2009-04-01 2009-01-03 1988-12-23 
14962 1988-10-17 1999-10-14 2009-04-02 2009-01-04 1988-12-24 
14963 1988-10-18 1999-10-15 2009-04-03 2009-01-05 1988-12-25 
14964 1988-10-19 1999-10-16 2009-04-04 2009-01-06 1988-12-26 
14965 1988-10-20 1999-10-17 2009-04-05 2009-01-07 1988-12-27 

這需要多一點的時間少了,大概是因爲日期值已預先caclulated。

+0

好的,謝謝。我們快到了。缺少的東西是對於10,000個列中的每一列,我需要365 * 41個後續行,其中的日期取自原始data.frame。當行到達data.frame的末尾時(即2014-12-21),它們應該從頭開始重新開始。換句話說,從df中取得了10000個列和14,965個日期行。這很難嗎?謝謝 – aaaaa

+0

沒問題,你也希望日期環繞原始範圍。容易做到這一點的一種方法是從原始表中複製原始表和子集,而不是標準日期算法;我將添加一個代碼示例。 – gringer

2

試試這一個,使用子集來代替:

start_day = as.Date('1974-01-01', format = '%Y-%m-%d') 
end_day = as.Date('2014-12-21', format = '%Y-%m-%d') 

date_vec <- seq.Date(from=start_day, to=end_day, by="day") 

現在,我創建了一個向量足夠長的時間,這樣我可以用簡單的子集以後:

date_vec2 <- rep(date_vec,2) 

現在,創建隨機啓動日期爲100個實例(用您的應用程序將其替換爲10000):

random_starts <- sample(1:14965, 100) 

現在,創建一個通過簡單地用你所需要的長度子集化date_vec2日期列表:

dates <- lapply(random_starts, function(x) date_vec2[x:(x+14964)]) 
date_df <- data.frame(dates) 
names(date_df) <- 1:100 

date_df[1:5,1:5] 

      1   2   3   4   5 
1 1997-05-05 2011-12-10 1978-11-11 1980-09-16 1989-07-24 
2 1997-05-06 2011-12-11 1978-11-12 1980-09-17 1989-07-25 
3 1997-05-07 2011-12-12 1978-11-13 1980-09-18 1989-07-26 
4 1997-05-08 2011-12-13 1978-11-14 1980-09-19 1989-07-27 
5 1997-05-09 2011-12-14 1978-11-15 1980-09-20 1989-07-28 
+0

好的......謝謝你,但你錯過了一個非常快的步驟。 date_df有一個額外的行,它引入了一個副本。所以....如果你更新你的答案是這樣的:date_df = date_df [-c(14966),]我會把它標記爲正確的。謝謝 – aaaaa

+0

感謝您的指針。現在應該是正確的。 – coffeinjunky