按不同的N复制行

时间:2015-08-07 14:52:57

标签: r

我有以下数据

mydata <- data.frame(id=c(1,2,3,4,5), n=c(2.63, 1.5, 0.5, 3.5, 4))

1)我需要为每个id重复行数n。例如,对于id = 1,n = 2.63,那么我需要将id = 1行复制三次。如果n = 0.5,那么我只需要复制一次......所以n需要进行整理。

2)创建一个名为t的新变量,其中每个id的t之和必须等于n。

3)创建另一个名为cumulative.t

的新变量

输出如下:

id  n   t   accumulated.t
1   2.63    1   1
1   2.63    1   2
1   2.63    0.63    2.63
2   1.5 1   1
2   1.5 0.5 1.5
3   0.5 0.5 0.5
4   3.5 1   1
4   3.5 1   2
4   3.5 1   3
4   3.5 0.5 3.5
5   4   1   1
5   4   1   2
5   4   1   3
5   4   1   4

2 个答案:

答案 0 :(得分:4)

获取ceiling的&#39; n&#39;列和用于扩展&#39; mydata&#39;的行。 (rep(1:nrow(mydata), ceiling(mydata$n))

使用data.table,我们会转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(mydata1)),按&#39; id&#39;分组我们复制(rep)1,times指定为&#39; n&#39;的第一个值trunc。 (rep(1, trunc(n[1])))。取出&#39; n&#39;的独特价值之间的差异。每个小组和sum的&#39; tmp&#39; (n[1]-sum(tmp))。如果差异大于0,我们会连接&#39; tmp&#39;和&#39; tmp2&#39; (c(tmp, tmp2))或者如果它是&#39; 0&#39;,我们只接受&#39; tmp&#39;。这可以放在list中,以创建两列&#39; t&#39;以及&#39; tmp3(cumsum(tmp3))的累积总和。

 library(data.table)
 mydata1 <- mydata[rep(1:nrow(mydata),ceiling(mydata$n)),]
 setDT(mydata1)[, c('t', 'taccum') := {
         tmp <- rep(1, trunc(n[1]))
         tmp2 <- n[1]-sum(tmp)
         tmp3= if(tmp2==0) tmp else c(tmp, tmp2)
         list(tmp3, cumsum(tmp3)) },
                                  by = id]
 mydata1
#  id    n    t taccum
# 1:  1 2.63 1.00   1.00
# 2:  1 2.63 1.00   2.00
# 3:  1 2.63 0.63   2.63
# 4:  2 1.50 1.00   1.00
# 5:  2 1.50 0.50   1.50
# 6:  3 0.50 0.50   0.50
# 7:  4 3.50 1.00   1.00
# 8:  4 3.50 1.00   2.00
# 9:  4 3.50 1.00   3.00
#10:  4 3.50 0.50   3.50
#11:  5 4.00 1.00   1.00
#12:  5 4.00 1.00   2.00
#13:  5 4.00 1.00   3.00
#14:  5 4.00 1.00   4.00

答案 1 :(得分:0)

利用基础R的替代方案。

mydata <- data.frame(id=c(1,2,3,4,5), n=c(2.63, 1.5, 0.5, 3.5, 4))
mynewdata <- data.frame(id = rep(x = mydata$id,times = ceiling(x = mydata$n)),
                        n = mydata$n[match(x = rep(x = mydata$id,ceiling(mydata$n)),table = mydata$id)],
                        t = rep(x = mydata$n / ceiling(mydata$n),times = ceiling(mydata$n)))
mynewdata$t.accum <- unlist(x = by(data = mynewdata$t,INDICES = mynewdata$id,FUN = cumsum))

我们首先创建一个包含三列data.frameidn的{​​{1}}。使用tid计算rep,以重复ID变量适当次数。使用ceilingn中查找正确的值,即可获得match。通过获取mydata$n的{​​{1}}和t的比率,然后重复适当的次数(在这种情况下,n获得ceiling再次n

然后,我们使用ceiling获取累计总和,使用n调用以允许每组ID的分组处理。你也可以在这里使用cumsum