扩展一个大型数据框,同时将两个变量与第三个变量相同

时间:2014-05-09 14:26:17

标签: r

我是R的新手并且在堆栈溢出方面进行了大量研究,但仍无法解决我的问题。我需要扩展包含4个变量的数据集:

date          kid  kid2  sums  
01/01/2012    A    12    123    
01/10/2012    A    15    100    
01/03/2012    B    10    900   
01/01/2012    C    10    100

期望的输出:我已经扩展到2012年10月1日:

date    kid kid2    sums    
1/1/2012    A   12  123 
1/2/2012    A   12  0   *
1/3/2012    A   12  0   *
1/4/2012    A   12  0   *
1/5/2012    A   12  0   *
1/6/2012    A   12  0   *
1/7/2012    A   12  0   *
1/8/2012    A   12  0   *
1/9/2012    A   12  0   *
1/10/2012   A   15  100 
1/1/2012    B   10  900 
1/2/2012    B   10  0   *
1/3/2012    B   10  900 
1/4/2012    B   10  0   *
1/5/2012    B   10  0   *
1/6/2012    B   10  0   *
1/7/2012    B   10  0   *
1/8/2012    B   10  0   *
1/9/2012    B   10  0   *
1/10/2012   B   10  0   *
1/1/2012    C   10  100 
1/2/2012    C   10  0   *
1/3/2012    C   10  0   *
1/4/2012    C   10  0   *
1/5/2012    C   10  0   *
1/6/2012    C   10  0   *
1/7/2012    C   10  0   *
1/8/2012    C   10  0   *
1/9/2012    C   10  0   *
1/10/2012   C   10  0   *

我需要以这样一种方式进行扩展:对于数据中的kidkid2的每个给定组合,我需要在2012年1月的所有日期中分布数据,并且对于添加了新分配的行总结为O。

我的数据集非常庞大,数百万行,所以我正在寻找一种最佳,最有效的方法。

我正在考虑使用展开/网格,但我不确定如何将(kidkid2)组合保留为数据,然后分布在所有缺失日期。

感谢您的帮助。

SJ

2 个答案:

答案 0 :(得分:1)

这是一个解决方案。首先,请阅读您的数据:

df <- read.table(text="date          kid  kid2  sums  
01/01/2012    A    12    123    
01/10/2012    A    15    100    
01/03/2012    B    10    900   
01/01/2012    C    10    100", header=TRUE)

然后将日期转换为Date格式:

df$date <- as.Date(df$date, format="%m/%d/%Y")

现在我将创建一个包含所需日期的向量,从1月1日到31日。

dates <- seq(as.Date("01/01/2012", format="%m/%d/%Y"),as.Date("01/31/2012", format="%m/%d/%Y"), by="day") 

有了这个,我们可以用日期和孩子的所有组合创建一个新的data.frame

df2<-merge(dates, df[,c(-1, -4)], by=NULL)
names(df2)[1] <- "date"

要获得原始金额,我们可以合并它们,但保留所有结果,并重新排序以使其达到您想要的顺序:

df3<-merge(df, df2, all=TRUE)
df3<-df3[order(df3$kid,df3$kid2, df3$date), ]

最后,如果您愿意,可以将NA替换为0&#39;

df3<-replace(df3, is.na(df3), 0)

答案 1 :(得分:0)

这是另一种方法。

#sample data
df<-data.frame(
    date = c("01/01/2012", "01/10/2012", "01/03/2012", "01/01/2012"),
    kid = c("A", "A", "B", "C"),
    kid2 = c(12, 15, 10, 10),
    sums = c(123,100, 900, 100)
)

#borrow from @Carlos
dates <- as.character(seq(as.Date("01/01/2012", format="%m/%d/%Y"),
    as.Date("01/31/2012", format="%m/%d/%Y"), by="day"),
    format="%m/%d/%Y"
)

#now create factors
df$date<-factor(df$date, levels=dates)
df$kid2<-factor(df$kid2)
df$kk<-interaction(df$kid, df$kid2, drop=T)

#so we can use xtab
dd <- as.data.frame(xtabs(sums~date+kk, df))

#optionally, split back apart kid/kid2
dd <- cbind(dd, 
   `colnames<-`(do.call(rbind,
        strsplit(as.character(dd$kk),".", fixed=T)
    ),c("kid","kid2"))
)