R:复制一行并在每行的下一个日期前更新

R:复制一行并在每行的下一个日期前更新,r,date,replicate,R,Date,Replicate,输入及其预期的输出表明,我希望复制输入行并更新日期条目。我该怎么做 输入 > aa<- data.frame(a=c(1,11,111),b=c(2,22,222),length=c(3,5,1),date=c(as.Date("28.12.2016",format="%d.%m.%Y"), as.Date("30.12.2016",format="%d.%m.%Y"), as.Date("01.01.2017",format="%d.%m.%Y"))) > aa a

输入及其预期的输出表明,我希望复制输入行并更新日期条目。我该怎么做

输入

> aa<- data.frame(a=c(1,11,111),b=c(2,22,222),length=c(3,5,1),date=c(as.Date("28.12.2016",format="%d.%m.%Y"), as.Date("30.12.2016",format="%d.%m.%Y"), as.Date("01.01.2017",format="%d.%m.%Y")))
> aa
    a   b length       date
1   1   2      3 2016-12-28
2  11  22      5 2016-12-30
3 111 222      1 2017-01-01
  a   b length       date
1 1   2      3 2016-12-28
2 1   2      3 2016-12-29
3 1   2      3 2016-12-30
4 11  22     5 2016-12-30
5 11  22     5 2016-12-31
6 11  22     5 2017-01-01
7 11  22     5 2017-01-02
8 11  22     5 2017-01-03
9 111 222    1 2017-01-01

不像使用dplyr和data.table包的包那样优雅,但级别较低:

replicaterow1 <- function(df1 = aa) {
    newdf <- df1[0,]
    rowss <- nrow(df1)
    rowcount <- 1
    for (i in 1:rowss) {
        rowi <- df1[i,]
        reps <- as.integer(rowi[3])
        newrow <- rowi
        newdf[rowcount,] <- rowi
        rowcount <- rowcount + 1
        if (reps > 1) {
            for(j in 1:(reps-1)) {
                newrow[4] <- newrow[4] + 1
                newdf[rowcount,] <- newrow
                rowcount <- rowcount + 1
            }
        }
    }
    return(newdf)
}
replicaterow1


您可以使用
base
dplyr
data.table
进行分组操作。首先重复这些行以获得正确的新数据大小。然后增加天数

library(dplyr)
aa2 <- aa[rep(1:nrow(aa), aa$length),]
aa2 %>% group_by(a,b) %>% mutate(date= date + 1:n() - 1L)
# Source: local data frame [9 x 4]
# Groups: a, b [3]
# 
#       a     b length       date
#   <dbl> <dbl>  <dbl>     <date>
# 1     1     2      3 2016-12-28
# 2     1     2      3 2016-12-29
# 3     1     2      3 2016-12-30
# 4    11    22      5 2016-12-30
# 5    11    22      5 2016-12-31
# 6    11    22      5 2017-01-01
# 7    11    22      5 2017-01-02
# 8    11    22      5 2017-01-03
# 9   111   222      1 2017-01-01

#data.table
library(data.table)
aa2 <- aa[rep(1:nrow(aa), aa$length),]
setDT(aa2)[, date := date + 1:.N - 1L, by= .(a,b)]

#base
aa2 <- aa[rep(1:nrow(aa), aa$length),]
transform(aa2, date=ave(date, a, FUN=function(x) x + 1:length(x) - 1L))

不要过分简化示例,您的数据帧真的只有一行吗?@Pierrelaffortune用另外两个条目更新了最小工作示例。我被要求提供更长的示例,因此添加了两个额外条目,请注意,数据可以有多个条目,长度和行复制到下一个日期的次数。此函数不使用长度字段…存在一些小错误,使用更大的示例进行测试,其中第四行到第九行的日期输入错误,请参阅更新的MWE。您能推荐使用哪种方法吗?我喜欢1.1,1.2,2.1,2.2,2.3,2.4,2.5的基本解决方案。。。但是,每种选择的优缺点是什么?这取决于您的工作流程。如果您已经有了一个dplyr管道序列,那么继续使用相同的包是有意义的。如果您已经在项目的其余部分使用了
data.table
,那么使用该软件包是有意义的。包的内部结构略有不同
dplyr
将输出一个
tbl\u df
。data.table将输出一个
data.table
。这些仍然是表数组,但如果您不习惯它们,它们的行为可能会略有不同。如果我可以做出选择呢?
dplyr
是最新的候选,最容易学习吗?是的,对新用户来说非常容易。但是学习
base R
有助于真正“掌握语言”。
data.table
快速而强大,但需要更多的前期学习。base R的优化程度不如分组操作的包。在
aggregate
ave
tapply
中迷路可能会让人头疼。最终学习这些是很好的,但要想起步,
dplyr
是最为用户友好的。但一旦您学习了
data.table
,您就可以使用更大的数据集和简洁的语法。
   a b length       date
1: 1 2      3 2016-12-28
2: 1 2      3 2016-12-29
3: 1 2      3 2016-12-30
library(dplyr)
aa2 <- aa[rep(1:nrow(aa), aa$length),]
aa2 %>% group_by(a,b) %>% mutate(date= date + 1:n() - 1L)
# Source: local data frame [9 x 4]
# Groups: a, b [3]
# 
#       a     b length       date
#   <dbl> <dbl>  <dbl>     <date>
# 1     1     2      3 2016-12-28
# 2     1     2      3 2016-12-29
# 3     1     2      3 2016-12-30
# 4    11    22      5 2016-12-30
# 5    11    22      5 2016-12-31
# 6    11    22      5 2017-01-01
# 7    11    22      5 2017-01-02
# 8    11    22      5 2017-01-03
# 9   111   222      1 2017-01-01

#data.table
library(data.table)
aa2 <- aa[rep(1:nrow(aa), aa$length),]
setDT(aa2)[, date := date + 1:.N - 1L, by= .(a,b)]

#base
aa2 <- aa[rep(1:nrow(aa), aa$length),]
transform(aa2, date=ave(date, a, FUN=function(x) x + 1:length(x) - 1L))
setDT(aa)[ , .(date = date + 1:length - 1), by = .(a, b)]