【发布时间】:2016-02-01 00:00:15
【问题描述】:
我有一个数据框,其中每一行都有一个唯一的 ID。我需要根据开始日期与结束日期和批准日期的最大值之间的天数复制这些行中的每一行。
ID <- c(1,2)
Value <- c(10,20)
StartDate <- c(as.Date("01/01/2015", '%d/%m/%Y'),
as.Date("01/01/2015", '%d/%m/%Y'))
EndDate <- c(as.Date("31/01/2015", '%d/%m/%Y'),
as.Date("15/01/2015", '%d/%m/%Y'))
AppDate <- c(as.Date("15/01/2015", '%d/%m/%Y'),
as.Date("15/02/2015", '%d/%m/%Y'))
df <- data.frame(ID, Value, StartDate, EndDate, AppDate)
df <- df[rep(row.names(df), ifelse(as.numeric(df$AppDate) >
as.numeric(df$EndDate),as.numeric(df$AppDate-df$StartDate),
as.numeric(df$EndDate-df$StartDate)) + 1),]
然后我需要添加从开始日期到结束日期或批准日期的最大值的顺序日期列表。
我已经通过 2 个循环完成了这项工作。外部循环遍历每个唯一 ID 的数据帧。然后第二个循环遍历 ID 并添加日期。一旦第二个循环完成,它会将行传递到外部循环作为新的起点。
IDs <- unique(df$ID)
df$Days <- rep(as.Date("01/01/1999",'%d/%m/%Y'), nrow(df))
counter <- 1
for (i in 1:length(IDs)) {
ref <- IDs[i]
start <- 1
while (df$ID[counter] == ref) {
ifelse(start == 1, df$Days[counter] <- df$StartDate[counter],
df$Days[counter] <- df$StartDate[counter] + start -1)
ifelse (counter > nrow(df), break, counter <- counter + 1)
ifelse (counter > nrow(df), break, start <- start + 1)
}
}
我的实际数据集有超过 6,000 个 ID,一旦我复制了行,它最终会超过 500,000 行。循环运行时间超过 15 分钟,因此显然效率很低。
所以我想我有 2 个问题。
1)。在R中执行此操作的最有效方法是什么
2)。一般来说,这样做最有效的方法是什么,即说像 C++ 之类的东西
谢谢
【问题讨论】:
-
我认为本问答中的
data.table答案提供了有效解决方案的一般原则:Expanding a sequence in a data frame。谷歌“R expand date range data.table”应该提供几个类似的例子。
标签: r loops for-loop nested-loops