如何在R中扩展大型数据框

时间:2014-02-27 04:51:49

标签: r plyr expand reshape dplyr

我有一个数据框

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列(我的实际数据集中有spp的17个唯一值。)

对于id的每个值,date都是相同的(例如,当id = 2时,date始终= 1985-08-01)。在我的真实数据集中,除sppy之外的所有列均可由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*
  • 表示添加的行

我可能不得不在未来使用可能更大的数据帧来实现这一点,因此可以理解快速,高效(时间和内存)的方式,但任何解决方案都会让我满意。我认为应该有方法可以使用dplyrdata.tablereshape包,但我对它们中的任何一个都不是很熟悉。我不确定是否最简单地扩展行id,spp和y,然后执行left_join()merge()重新组合日期(以及我的实际数据帧中的所有其他变量)在id

3 个答案:

答案 0 :(得分:5)

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有所帮助,可能是{{1}}更有效的方法。

答案 1 :(得分:2)

我会采取第二种方式,希望这有助于

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)

答案 2 :(得分:2)

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