2017-01-18 8 views
0

私は、株価、のようなものが含まれているデータフレームを持っています。私はデータを連続した時系列にサブセット化することを考えています(週末は無視しています)。私は株式数と時間の間のトレードオフに直面する(すなわち、時系列が長くなればなるほど、シリーズ全体で利用可能なデータが少ない企業)。見つける連続実行が

私は、シリーズを選ぶための最適な方法は、株式の実行の開始日と(おそらく異なる)株式の実行の終了日が含まれていることです。それ以外の期間は、時間範囲を最大化するものではありません。最後に、可能な開始日、終了日、および企業の数を含むデータフレームを期待しています。私はどの時間範囲が最も適しているかを決めることができます。

私はこれがはっきりしていることを願っておりますが、明確化が必要な場合はお知らせください。

編集:これが役立ちます。ここで私は、この出力のために願っていた粗データフレーム

date1 <- seq(as.Date("2006/1/1"), as.Date("2010/1/1"), "days") 
date2 <- seq(as.Date("2006/6/12"), as.Date("2008/1/1"), "days") 
date3 <- seq(as.Date("2009/10/11"), as.Date("2010/12/1"), "days") 
date4 <- seq(as.Date("2002/1/1"), as.Date("2007/1/13"), "days") 

row_to_drop1 <- !(weekdays(as.Date(date1)) %in% c('Saturday','Sunday')) 
row_to_drop2 <- !(weekdays(as.Date(date2)) %in% c('Saturday','Sunday')) 
row_to_drop3 <- !(weekdays(as.Date(date3)) %in% c('Saturday','Sunday')) 
row_to_drop4 <- !(weekdays(as.Date(date4)) %in% c('Saturday','Sunday')) 

date1 <- date1[row_to_drop1] 
date2 <- date2[row_to_drop2] 
date3 <- date3[row_to_drop3] 
date4 <- date4[row_to_drop4] 

mydf <- rbind.data.frame(data.frame(id = 1, date = date1),data.frame(id=2,date=date2),data.frame(id=2,date=date3),data.frame(id=3,date=date4)) 

です:

start  end   #ofids 
1/1/2006 1/1/2010 1 
6/12/2006 1/1/2010 2 
10/11/2009 1/1/2010 3 
1/1/2002 1/1/2010 3 
1/1/2006 1/1/2008 3 
6/12/2006 1/1/2008 1 
10/11/2009 1/1/2008 2 
1/1/2002 1/1/2008 3 
1/1/2006 12/1/2010 1 
6/12/2006 12/1/2010 3 
10/11/2009 12/1/2010 2 
1/1/2002 12/1/2010 2 
1/1/2006 1/13/2007 2 
6/12/2006 1/13/2007 1 
10/11/2009 1/13/2007 1 
1/1/2002 1/13/2007 1 

だけで構成されて#ofidsが、うまくいけば、それは全体のポイントを取得します。開始日が終了日より長くてはならないため、一部の行は削除されます。

start  end 
1/1/2006 1/1/2010 
6/12/2006 1/1/2010 
10/11/2009 1/1/2010 
1/1/2002 1/1/2010 
1/1/2006 1/1/2008 
6/12/2006 1/1/2008 
1/1/2002 1/1/2008 
1/1/2006 12/1/2010 
6/12/2006 12/1/2010 
10/11/2009 12/1/2010 
1/1/2002 12/1/2010 
1/1/2006 1/13/2007 
6/12/2006 1/13/2007 
1/1/2002 1/13/2007 

14x3(IDS)= 42行のために作る必要があります。

は、ここで実行されます(すべての終了日と開始日のコンボ)です。

+0

希望の出力?それぞれの 'id'の' date'の範囲だけですか?それは単なる集約です。 – alistaire

+0

@alistaire可能なすべての範囲とその範囲で使用可能なIDの数。可能な範囲は、在庫の連続ストレッチの開始日のペアです(ただし必ずしも同じ在庫ではありません。すべての開始日と終了日のデカルト積を取る必要があります)。 – Almacomet

+0

どのように「連続」を定義していますか?市場が開いている日?それは別のデータセットを必要とするでしょう(またはあなたが持っているものから推論する必要があります)。サンプルの目的の結果を含めて、サンプルを編集して[再現可能]にする必要があります(http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example#5963610)。データ。 – alistaire

答えて

0

データを集計する2つの方法があります。まず、市場が開いているときのベクトルを作る必要があります。ここでは平日を使用しますが、実際のカレンダーはもっと複雑になる傾向があります。このようなベクトルを取得する簡単な方法は、その期間にその取引所で継続的に取引されていることがわかっているインデックスのデータをquantmodなどでプルし、日付を引き出​​すことです。計算の各id

一つの方法のための

library(dplyr) # Use another grammar if you prefer 

# Make a vector of dates the market is open 
mkt_open <- seq(min(mydf$date), max(mydf$date), '1 day') 
mkt_open <- mkt_open[!(weekdays(mkt_open) %in% c('Saturday','Sunday'))] 

実行し、それが取引するかしない各idのための実行を理解することです。 full_joinを使用してNAを会社が取引するかどうかのブール変数に挿入すると、実行ごとにID(シーケンシャルな整数)を返すdata.table::rleidを使用できます。 (base::rleでも同じことができますが、それ以上の作業です)。一度グループ化すると、データを簡単に要約するのは簡単です。あなたが唯一の企業がfilter(trading) %>% select(-trading)に、タックを取引されて実行さを気にした場合

mydf %>% mutate(trading = TRUE) %>% # Add index column which will add NAs in join 
    # Insert missing dates for each id 
    full_join(crossing(id = unique(.$id), date = mkt_open)) %>% 
    mutate(trading = coalesce(trading, FALSE)) %>% # Replace NAs with FALSE 
    group_by(id) %>% 
    arrange(date) %>% # Sort by date before calculating runs 
    group_by(run_id = data.table::rleid(trading), trading, add = TRUE) %>% # Add ID to separate runs 
    summarise(run_length = n(), # Count rows per group 
       start = min(date), 
       end = max(date)) 

#> Source: local data frame [9 x 6] 
#> Groups: id, run_id [?] 
#> 
#>  id run_id trading run_length  start  end 
#> <dbl> <int> <lgl>  <int>  <date>  <date> 
#> 1  1  1 FALSE  1044 2002-01-01 2005-12-30 
#> 2  1  2 TRUE  1045 2006-01-02 2010-01-01 
#> 3  1  3 FALSE  238 2010-01-04 2010-12-01 
#> 4  2  1 FALSE  1159 2002-01-01 2006-06-09 
#> 5  2  2 TRUE  407 2006-06-12 2008-01-01 
#> 6  2  3 FALSE  463 2008-01-02 2009-10-09 
#> 7  2  4 TRUE  298 2009-10-12 2010-12-01 
#> 8  3  1 TRUE  1314 2002-01-01 2007-01-12 
#> 9  3  2 FALSE  1013 2007-01-15 2010-12-01 

。あなたは、個々の実行よりも、取引企業の数がもっと気になる場合、あなたはid初を集約することができます

を取引企業の数によって


実行します:あなたは何

mydf %>% group_by(date) %>% 
    summarise(no_ids = n_distinct(id)) %>% # Count ids per date 
    full_join(data.frame(date = mkt_open)) %>% # Add any dates w/o trading 
    mutate(no_ids = coalesce(no_ids, 0L)) %>% # Fill NAs for days w/o trading with 0 
    arrange(date) %>% 
    group_by(run_id = data.table::rleid(no_ids), no_ids) %>% 
    summarise(run_length = n(), 
       start = min(date), 
       stop = max(date)) 

#> Source: local data frame [7 x 5] 
#> Groups: run_id [?] 
#> 
#> run_id no_ids run_length  start  stop 
#> <int> <int>  <int>  <date>  <date> 
#> 1  1  1  1044 2002-01-01 2005-12-30 
#> 2  2  2  115 2006-01-02 2006-06-09 
#> 3  3  3  155 2006-06-12 2007-01-12 
#> 4  4  2  252 2007-01-15 2008-01-01 
#> 5  5  1  463 2008-01-02 2009-10-09 
#> 6  6  2   60 2009-10-12 2010-01-01 
#> 7  7  1  238 2010-01-04 2010-12-01 

+0

私はここからそれを得たと思う。私はmydf $ startを取ってmydf $ stop(取引をフィルタリングした後== true)に渡すことができます。それから私はmydfとそれを交差させ、それが範囲内にあることを確認します。ありがとう! – Almacomet

+0

'%>%ungroup()%>%フィルタ(取引)%>%(%)unlist()%>%ユニーク()%>%コンボ(2)%> (%、%、%、%、%、%、%、%、%、%);%1% ) '最初のものに?私はあなたがこれらの範囲のために何を探しているのかよく分かりません。最大の企業はアクティブですか?分?何が起こっているかを見ることができるように、いくつかのビジュアライゼーションを作成する方が便利かもしれません。 – alistaire

関連する問題