我正在创建一个假数据集,并且希望基本上分解一个总和以创建我可以用随机日期填充的虚拟行。
例如,我的df
可能如下所示:
id orders skips
joe 3 0
mary 2 1
jack 5 1
我想制作的是data.frame
或data.table
看起来像这样,成功order
为1
,跳过为0
:< / p>
id order
joe 1
joe 1
joe 1
mary 1
mary 0
mary 1
jack 1
jack 1
jack 1
jack 1
jack 0
jack 1
ADDITION:理想情况下,如果可能,0
值会随机混合/夹在1
值之间。这是由于数据集将在问题集中用于什么的怪癖。
在一个完美的世界中,我会将给定范围内的随机start_date
分配给id
内的每个订单,以便:
id order date
joe 1 1/2/2016
joe 1 1/3/2016
joe 1 1/8/2016
mary 1 1/10/2016
mary 0 1/3/2016
mary 1 1/5/2016
jack 1 1/7/2016
jack 1 1/2/2016
jack 1 1/1/2016
jack 1 1/10/2016
jack 0 1/12/2016
jack 1 1/15/2016
我最初认为我可以使用dcast
和reshape
的组合来欺骗R制作数据集,例如dcast(df,id~orders,fun.aggregate=length)
,但这会让我走错了路。
但是,在他们爬行之前必须走路。有人能帮忙吗?
答案 0 :(得分:2)
以下是data.table
的一种方法:
dt[, .(order = rep(c(1, 0), c(orders, skips))), by = "id"]
# id order
#1: joe 1
#2: joe 1
#3: joe 1
#4: mary 1
#5: mary 1
#6: mary 0
#7: jack 1
#8: jack 1
#9: jack 1
#10: jack 1
#11: jack 1
#12: jack 0
数据:
library(data.table)
dt <- fread(
"id orders skips
joe 3 0
mary 2 1
jack 5 1"
)
答案 1 :(得分:0)
您可以使用tapply
(或split
和lapply
,如果您愿意)在基地R中执行此操作,然后rbind
将所有内容重新组合在一起:
df2 <- do.call(rbind, tapply(df, df$id,
function(x){
data.frame(id = rep(x$id, sum(x$orders, x$skips)),
order = sample(rep(c(1, 0), c(x$orders, x$skips)))
)
}))
rownames(df2) <- NULL
其中tapply
在df$id
组之间运行匿名函数,do.call(rbind,
将列表重新排列为单个data.frame
。匿名函数会data.frame
rep
消耗id
所需的次数,并使用sample
随机播放0和1 rep
eated orders
和skips
次分别。
一次打嗝,应该是可以解决的:rbind
会自动创建行名,这些行名称既丑陋又不必要。有一个论点可以解决这个问题,但是我无法正确地将它安排在do.call
结构中,所以上面只是在第二行中删除它们。 (如果您知道正确的地方make.row.names = FALSE
,请发表评论并进行编辑。)
结果:
> df2
id order
1 jack 0
2 jack 1
3 jack 1
4 jack 1
5 jack 1
6 jack 1
7 joe 1
8 joe 1
9 joe 1
10 mary 1
11 mary 0
12 mary 1