2

私はいくつかの(金融時系列)データを背の高い形式で持っています:

require(data.table)
DT <- data.table(Variable=c(rep("a",times = 3), rep("b", times=3)), 
                 Date=as.Date(c("2014-04-01","2014-04-02","2014-04-03"
                                ,"2014-04-02", "2014-04-03","2014-04-04")),
                 Value=c(1:3,3:1), key=c("Variable","Date"))

DT

   Variable       Date Value
1:        a 2014-04-01     1
2:        a 2014-04-02     2
3:        a 2014-04-03     3
4:        b 2014-04-02     3
5:        b 2014-04-03     2
6:        b 2014-04-04     1

共通の行ごとspreadに3 番目の変数を計算したいと思います(基本的には、2 つの時系列間のスプレッド - 金融ドメインでの共通の変換)。spread = a - bDate

望ましい出力:

   Variable       Date Value
1:   spread 2014-04-02    -1
2:   spread 2014-04-03     1

dcast.data.tableデータをワイド形式 (つまり、列を含むテーブル) に変換するときの解決策を知っていますが、大きなデータでのパフォーマンスの問題により、a)と b)c("Date", "a", "b")を使用してトール形式で直接これを行うエレガントな方法はありますか( 2 部構成の質問)?dplyrdata.table

理想的には、 のdplyrような表現力のあるものを探していmutate(tbl_dt(DT, tall=TRUE), spread=a-b)ます。(免責事項: 私は完全な初心者ですdplyr)

実際のデータセット:

# download 200 stocks from Quandl.com. requires free registration
library(Quandl); library(data.table); library(plyr)
ntickers <- 200 ; auth.token="register_free_to_obtain_token"
code.file <- tempfile()
download.file("https://s3.amazonaws.com/quandl-static-content/quandl-stock-code-list.csv",
              destfile=code.file)
tickers <- na.omit(read.csv2(code.file, sep=",", stringsAsFactors=FALSE)[,"Price.Code"])
lst <- na.omit(tickers)[1:ntickers]
names(lst) <- lst
Q <- ldply(lst, Quandl, 
           type = "raw", end_date="2014-04-08", 
           sort="asc", auth=auth.token) # might take minutes
DT <- as.data.table(Q)[,Date:=as.IDate(Date)]
setnames(DT, ".id", "Instrument")
setkey(DT, Instrument, Date)

> dim(DT); object.size(DT)
[1] 685512      8
41145752 bytes
> DT
              Instrument       Date Open High  Low Close Volume Adjusted Close
     1:    GOOG/AMEX_ABI 1981-03-11   NA   NA 6.56  6.75 217200             NA
     2:    GOOG/AMEX_ABI 1981-03-12   NA   NA 6.66  6.88 616400             NA
     3:    GOOG/AMEX_ABI 1981-03-13   NA   NA 6.81  6.84 462000             NA
     4:    GOOG/AMEX_ABI 1981-03-16   NA   NA 6.81  7.00 306400             NA
     5:    GOOG/AMEX_ABI 1981-03-17   NA   NA 6.88  6.88 925600             NA
    ---                                                                       
685508: YAHOO/TSX_AHX_TO 2014-04-02 0.75 0.75 0.75  0.75   5000           0.75
685509: YAHOO/TSX_AHX_TO 2014-04-03 0.79 0.82 0.75  0.82  25700           0.82
685510: YAHOO/TSX_AHX_TO 2014-04-04 0.81 0.81 0.78  0.80   4500           0.80
685511: YAHOO/TSX_AHX_TO 2014-04-07 0.80 1.05 0.80  0.96  40400           0.96
685512: YAHOO/TSX_AHX_TO 2014-04-08 0.95 0.96 0.90  0.95  21300           0.95
4

3 に答える 3

4

これで作業できるはずです:

> merge(DT["a", ], DT["b",], by="Date")
         Date Variable.x Value.x Variable.y Value.y
1: 2014-04-02          a       2          b       3
2: 2014-04-03          a       3          b       2

のヘルプ ページでmerge.data.tableは、X[Y,...] アプローチとの詳細な比較について FAQ 1.12 を読むことを提案しています。

于 2014-04-08T02:11:10.500 に答える
3

dplyr を使用したアプローチの 1 つを次に示します。まず、データを作成します。

require(dplyr)

df <- data.frame(
  Variable = rep(c("a", "b"), each = 3), 
  Date = rep(as.Date("2014-04-01") + 0:2, 2),
  Value = c(1:3, 3:1)
)

ワイド フォームにローテーションする代わりに、ベクトル化された比較を使用できます。

df %.% 
  group_by(Date) %.%
  summarise(spread = Value[Variable == "a"] - Value[Variable == "b"])

## Source: local data frame [3 x 2]
## 
##         Date spread
## 1 2014-04-01     -2
## 2 2014-04-02      0
## 3 2014-04-03      2

summarise()結果の長さが 1 である必要があるため、a または b の値が複数ある場合、これは正しく失敗します 。同じアプローチが data.table でも機能しますが、結果のチェックにはもう少し注意する必要があります (ここでは、dplyr に比べてデータ テーブルは厳密性が低く、柔軟性が高いため)。

BondedDust によって提案された結合アプローチを使用することもできます。dplyr は、data.table ほど便利ではありません。

a <- df %.% filter(Variable == "a") %.% select(-Variable)
b <- df %.% filter(Variable == "b") %.% select(-Variable)

inner_join(a, b, by = "Date") %.%
  mutate(spread = Value.x - Value.y)

##         Date Value.x Value.y spread
## 1 2014-04-01       1       3     -2
## 2 2014-04-02       2       2      0
## 3 2014-04-03       3       1      2
于 2014-04-08T14:27:51.583 に答える
2

これは、dcast.data.table を使用した data.table メソッドです。

NA の選択と速度向上に関して、次のような問題があります。

# Create Dataset
require(data.table)
require(reshape2)
DT <- data.table(Variable=c(rep("a",times = 3), rep("b", times=3)), 
             Date=as.Date(c("2014-04-01","2014-04-02","2014-04-03"
                            ,"2014-04-02", "2014-04-03","2014-04-04")),
             Value=c(1:3,3:1), key=c("Variable","Date"))

# using data.table
DT2 <- dcast.data.table(DT, Date ~ Variable, drop=FALSE) 
DT2[, spread:= a-b, by = Date][!is.na(spread),]
# Actually I'm not clear about the different between `drop= FALSE` and `drop = TRUE` 

これが出力です

         日付アブスプレッド
1: 2014-04-02 2 3 -1
2: 2014-04-03 3 2 1
于 2014-04-09T04:09:13.863 に答える