6

こんにちはすべて、私はRを初めて使用します。

「id」、「date」、「ret」列を持つ 2 つのパネル データ ファイルがあります。

ファイル A にはファイル B よりも多くのデータが含まれていますが、私は主にファイル B のデータを扱っています。

「id」と「date」の組み合わせが一意の識別子です。

B の各 (id、date) を検索するエレガントな方法はありますか?ファイル A から取得した過去 10 日間を取得し、それらを B に保存する必要がありますか?

私の単純な方法は、B のすべての行をループすることです。

for i in 1:length(B) {
    B$past10d[i] <- prod(1+A$ret[which(A$id == B$id[i] & A$date > B$date[i]-10 & A$date < B$date[i])])-1
}

しかし、ループには永遠にかかります。

あなたの考えに本当に感謝します。

どうもありがとうございました。

4

7 に答える 7

1

マージしてみましたか?

「2つのデータフレームを共通の列または行の名前でマージするか、他のバージョンのデータベース結合操作を実行してください。」

さらに、複合PKなどを一意の識別子として継続的に使用する場合は、ローカルのMySQL / PostgreSQL(RMySQL / RPostgreSQL)データベースを使用することをお勧めします。私にとって、SQLによるデータの再配置と、その後のビューからのdata.framesの使用は、ループするよりもはるかに簡単です。

于 2010-07-12T08:20:15.913 に答える
1

%in%重要なのは、ベクトル化してオペレーターを使用してデータフレームをサブセット化することだと思いますA。そして、価格は乱数ではないことはわかっていますが、ランダムウォークをコーディングしたくありませんでした... を使用して株価指数を作成しましたが、図書館pasteの指数を使用できると確信しています。パネルデータについて私が見つけた最高のものです。pdata.frameplm

A  <- data.frame(stock=rep(1:10, each=100), date=rep(Sys.Date()-99:0, 10), price=rnorm(1000))
B <- A[seq(from=100, to=1000, by=100), ]
A <- cbind(paste(A$stock, A$date, sep="-"), A)
B <- cbind(paste(B$stock, B$date, sep="-"), B)
colnames(A) <- colnames(B) <- c("index", "stock", "date", "price")
index <- which(A[, 1] %in% B[, 1])
returns <- (A$price[index] - A$price[index-10]) / A$price[index-10]
B <- cbind(B, returns)
于 2010-07-12T13:52:25.683 に答える
0

これはもっと速いですか?(B$idとB$dateの組み合わせは、どこにも複製されない一意の識別子であると想定しています-コードによって暗示されます)

B$idDate <- factor(B$id):factor(B$date)
B$past10 <- sapply(B$idDate, function(x){with(B[B$idDate == x,], 
    prod(1+A$ret[A$id == id & A$date > date-10 & A$date < date])-1)})
于 2010-07-12T04:59:08.243 に答える
0

おそらくメモリの問題を抱えていることを考えると、最初に A を削減すると役立つかもしれません。まず、余分な ID を取り除きます。

A <- A[A$id %in% B$id,]

A データセットを完全に削減しても、より多くのメモリを取得する必要があります。いくつかの変数を保存しないと不可能です。それにもかかわらず、絶対最小値を下回り、絶対最大値を上回るすべての日付を削減することで、多くのデータを取り除くことができます。

A <- A[A$date > (min(B$date) - 10) & A$date <= max(B$date),]

もちろん、これを id で修飾しないことで、可能な限り最小のバージョンの A を取得することはできませんが、十分に小さいことを願っています。

最初に提案したコードを実行して、まだメモリ エラーがあるかどうかを確認します。

B$idDate <- factor(B$id):factor(B$date)
B$past10 <- sapply(B$idDate, function(x){with(B[B$idDate == x,], 
    prod(1+A$ret[A$id == id & A$date > date-10 & A$date < date])-1)})
于 2010-07-12T23:17:38.220 に答える
0

A と B の両方でレプリケートされるデータがない場合rbindは、最も簡単な解決策です。

#Sample data
A <- data.frame(
  id = rep(letters[1:3], each = 13),
  date = Sys.Date() + -12:0,
  ret = runif(39)
)

B <- data.frame(
  id = rep(letters[5:6], each = 5),
  date = Sys.Date() + -4:0,
  ret = runif(10)
)

#Only take the last ten days from A
A_past_10_days <- A[A$date > Sys.Date() - 10,]

#Bind by rows
rbind(A_past_10_days, B)
于 2010-07-12T11:18:58.723 に答える
0

一般に、R でのループは避けるべきです。コードがベクトルで動作する場合は、はるかに高速です。

ran2 で提案されているように、マージを使用します。設定all.x = T(またはall.yまたはall) して、1 つ (またはその他または両方) のデータ フレームからすべての行を取得できます。これは迅速で、通常、どのフィールドを照合するかを自動的に判断します。それ以外の場合は、ルックアップ フィールドとしてby.x(andby.yまたは)を指定する必要があります。byその音によって、このフィールドを自分で作成する必要があるかもしれません (John のコメントによると)。

その後、日付でフィルタリングできます。

于 2010-07-12T11:48:00.107 に答える
0
library(data.table)
#create data
A  <- data.table(id=rep(1:10, each=40000), date=rep(Sys.Date()-99:0,  4000), ret=rnorm(400000))
B  <- data.table(id=rep(1:5,  each=10), date=rep(Sys.Date()-99:0),  ret=rnorm(50))

#find dates to compare against
n <- NROW(B)
B_long <- B[,.(id = rep(id,each=10),date = rep(date,each=10))]
s <- rep(-10:-1,n)
B_long[,date:=date + s]

#information in one column
B_long$com <- as.numeric(paste0(B_long$id,as.numeric(B$date)))
A$com <- as.numeric(paste0(A$id,as.numeric(A$date)))

#compare
setkey(A,com)
X <- A[com %in% B_long$com,]

この回答はリチャーズの回答に基づいていますが、質問をより対象としています。

重要なアイデアは、比較する ID 日付の組み合わせの 1 つのベクトルを作成することです。これは、2 番目のコード ブロックで発生します。

私のソリューションは data.table パッケージを使用していますが、いくつかの構文を変更すると data.frame で動作するはずです。しかし、data.table パッケージを使用すると、keycolumns の利点があります。

それでも問題が解決しない場合は、このアプローチを john の 2 番目の回答と最初の作物 A と組み合わせることができます。

于 2016-04-06T06:23:46.647 に答える