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)]