4

假设我有以下内容data.table

dt <- data.table(id=c(1,1,1,1,1,1,2,2,2,2),
           wday=c("mon","tue","wed","thu","fri","sat","mon","tue","thu","fri"),
           val=c(2,3,5,8,6,2,3,4,2,6))

    id wday val
 1:  1  mon   2
 2:  1  tue   3
 3:  1  wed   5
 4:  1  thu   8
 5:  1  fri   6
 6:  1  sat   2
 7:  2  mon   3
 8:  2  tue   4
 9:  2  thu   2
10:  2  fri   6

这是另一个聚合的结果data.table。它表示变量的计数 ( ),具体取决于不同个体 ( )val的工作日 ( )。问题是,在我的操作中,我失去了计数为 0 的工作日。wdayid

data.table所以问题是:如何通过为每个 id 插入与缺少的工作日一样多的行来有效地更新我的对象val=0

结果如下:

    id wday val
 1:  1  mon   2
 2:  1  tue   3
 3:  1  wed   5
 4:  1  thu   8
 5:  1  fri   6
 6:  1  sat   2
 7:  1  sun   0
 8:  2  mon   3
 9:  2  tue   4
10:  2  wed   0
11:  2  thu   2
12:  2  fri   6
13:  2  sat   0
14:  2  sun   0

非常感谢你的帮助。

4

2 回答 2

2

我现在能想到的一种直接方法是使用expand.grid来获取所有组合,然后将其用于子集allow.cartesian = TRUE

setkey(dt, "id", "wday")
vals <- c("mon", "tue", "wed", "thu", "fri", "sat", "sun")
idx <- expand.grid(vals, unique(dt$id))[, 2:1]
dt[J(idx), allow.cartesian=TRUE]

#     id wday val
#  1:  1  mon   2
#  2:  1  tue   3
#  3:  1  wed   5
#  4:  1  thu   8
#  5:  1  fri   6
#  6:  1  sat   2
#  7:  1  sun  NA
#  8:  2  mon   3
#  9:  2  tue   4
# 10:  2  wed  NA
# 11:  2  thu   2
# 12:  2  fri   6
# 13:  2  sat  NA
# 14:  2  sun  NA

或者,可以使用以下命令直接构建idx数据表CJ

dt[CJ(unique(dt$id),vals), allow.cartesian=TRUE]
于 2013-05-13T09:27:21.203 回答
1

match 和 ddply 的另一种可能性:

FUN <- function(x) {
y <- x$val[match(c("mon", "tue", "wed", "thu", "fri", "sat", "sun"), x$wday, nomatch=NA)]
y[is.na(y)] <- 0
y <- data.frame(wday=c("mon", "tue", "wed", "thu", "fri", "sat", "sun"), val=y)
y
}
ddply(dt, .(id), FUN)
于 2013-05-13T09:36:57.550 回答