R で大規模なデータフレームを拡張する方法
質問
データフレームがあります
df <- data.frame(
id = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 4),
date = c("1985-06-19", "1985-06-19", "1985-06-19", "1985-08-01",
"1985-08-01", "1990-06-19", "1990-06-19", "1990-06-19",
"1990-06-19", "2000-05-12"),
spp = c("a", "b", "c", "c", "d", "b", "c", "d", "a", "b"),
y = rpois(10, 5))
id date spp y
1 1 1985-06-19 a 6
2 1 1985-06-19 b 3
3 1 1985-06-19 c 7
4 2 1985-08-01 c 7
5 2 1985-08-01 d 6
6 3 1990-06-19 b 5
7 3 1990-06-19 c 4
8 3 1990-06-19 d 4
9 3 1990-06-19 a 6
10 4 2000-05-12 b 6
ID と spp のあらゆる組み合わせが存在するように拡張したいと考えています。 y = 0
現在データフレームにないすべての組み合わせに対して。現在、データフレームは約 100,000 行、15 列です。展開すると、約 300,000 列になります (17 個の一意の値があります) spp
私の実際のデータセットでは)。
のすべての値に対して、 id
の date
同じです(例:ID = 2 の場合、日付は常に 1985-08-01)。実際のデータセットでは、次を除くすべての列が spp
そして y
によって指定できます id
.
最終的には次のようなものにしたいです:
id date spp y
1 1985-06-19 a 6
1 1985-06-19 b 3
1 1985-06-19 c 7
1 1985-06-19 d 0*
2 1985-08-01 a 0*
2 1985-08-01 b 0*
2 1985-08-01 c 7
2 1985-08-01 d 6
3 1990-06-19 b 5
3 1990-06-19 c 4
3 1990-06-19 d 4
3 1990-06-19 a 6
4 2000-05-12 a 0*
4 2000-05-12 b 6
4 2000-05-12 c 0*
4 2000-05-12 d 0*
- 追加された行を示す
将来的には、はるかに大きなデータ フレームを使用してこれを実行する必要がある可能性があるため、これを迅速かつ効率的に (時間とメモリの) 行う方法があれば幸いですが、どのような解決策でも私は満足できます。を使用する方法があるはずだと思います dplyr
, data.table
, 、 または reshape
パッケージですが、どれもよく知りません。行 id、spp、y だけを展開してから実行するのが最も簡単かどうかはわかりません。 left_join()
または merge()
に基づいて日付(および実際のデータフレーム内の他のすべての変数)を再結合します id
?
解決
expand.grid
ここで便利な機能ですが、
mergedData <- merge(
expand.grid(id = unique(df$id), spp = unique(df$spp)),
df, by = c("id", "spp"), all =T)
mergedData[is.na(mergedData$y), ]$y <- 0
mergedData$date <- rep(levels(df$date),
each = length(levels(df$spp)))
データのサブセットに対して実際には何もしていないので、私はそうは思わない plyr
おそらくもっと効率的な方法で役に立ちます data.table
.
他のヒント
私は二度目に行くだろう、これが助けることを願っています
x<-unique(df$id)
y<-unique(df$spp)
newdf<-data.frame(x=rep(x,each=length(y)),y=rep(y, length(x)))
merged<-merge(newdf, df, by.x=c(x,y), by.y=c("id","spp"), all=T)
. 新しい機能があります complete
の開発版では tidyr
それはこれを行います。もちろん complete
用途 expand.grid
内部的に。
# get new version of tidyr
devtools::install_github("hadley/tidyr")
# load package
require(tidyr)
# calculations
complete(df, c(id, date), spp, fill = list(y = 0))
## id date spp y
## 1 1 1985-06-19 a 5
## 2 1 1985-06-19 b 3
## 3 1 1985-06-19 c 5
## 4 1 1985-06-19 d 0
## 5 2 1985-08-01 a 0
## 6 2 1985-08-01 b 0
## 7 2 1985-08-01 c 4
## 8 2 1985-08-01 d 9
## 9 3 1990-06-19 a 8
## 10 3 1990-06-19 b 3
## 11 3 1990-06-19 c 5
## 12 3 1990-06-19 d 6
## 13 4 2000-05-12 a 0
## 14 4 2000-05-12 b 3
## 15 4 2000-05-12 c 0
## 16 4 2000-05-12 d 0