我有一个包含以下信息的数据集:
id class year n
25 A63 2006 3
25 F16 2006 1
39 0901 2001 1
39 0903 2001 3
39 0903 2003 2
39 1901 2003 1
...
大约有10万个不同的ID和超过300个类。这一年从1998年到2007年各不相同。
我想要做的是,在发生一些id和类之后填补时间间隔,id和class为n = 0。
然后计算n的总和和类的数量。
例如,上述6行数据应扩展到下表:
id class year n sum Qc Qs
25 A63 2006 3 3 2 2
25 F16 2006 1 1 2 2
25 A63 2007 0 3 0 2
25 F16 2007 0 1 0 2
39 0901 2001 1 1 2 2
39 0903 2001 3 3 2 2
39 0901 2002 0 1 0 2
39 0903 2002 0 3 0 2
39 0901 2003 0 1 2 3
39 0903 2003 2 5 2 3
39 1901 2003 1 1 2 3
39 0901 2004 0 1 0 3
39 0903 2004 0 5 0 3
39 1901 2004 0 1 0 3
...
39 0901 2007 0 1 0 3
39 0903 2007 0 5 0 3
39 1901 2007 0 1 0 3
我可以通过丑陋的for循环解决它,它需要一个小时才能得到结果。有没有更好的方法呢?矢量化或使用data.table?
答案 0 :(得分:0)
使用expand.grid
获取cartesian product of class and year。
然后merge
您当前的数据框到这个新数据框。然后做经典子集替换。
df <- data.frame(class = as.factor(c("A63","F16","0901","0903","0903","1901")),
year = c(2006,2006,2001,2001,2003,2003),
n=c(3,1,1,3,2,1))
df2 <- expand.grid(class = levels(df$class),
year= 1997:2006)
df2 <- merge(df2,df, all.x=TRUE)
df2$n[is.na(df2$n)] <- 0
答案 1 :(得分:0)
使用dplyr
您可以尝试:
library(dplyr)
df%>% group_by(class,id) %>% arrange(year) %>%
do(merge(data.frame(year=c(.$year[1]:2007),id=rep(.$id[1],2007-.$year[1]+1),class=rep(.$class[1],2007-.$year[1]+1)),.,all.x=T))
它按类和ID对数据进行分组,并将每个组合并到一个数据框中,该数据框包含具有该组的ID和类的所有年份。
编辑:如果您只想在某个id
之后执行此操作:
as.data.frame(rbind(df[df$id<=25,],df%>% filter(id>25) %>% group_by(class,id) %>% arrange(year) %>%
do(merge(data.frame(year=c(.$year[1]:2007),id=rep(.$id[1],2007-.$year[1]+1),class=rep(.$class[1],2007-.$year[1]+1)),.,all.x=T))))