我需要将我的数据分成3个不同的时间段,但我希望以每个Y的间隙数最少(缺少数据)的方式进行。这是我的数据:
Data <- data.frame(
Y = c(rep("A",10),rep("B",10),rep("C",10),rep("D",10),rep("E",10)),
X = c(sample(seq(as.Date('2017/03/01'), as.Date('2017/09/01'), by="day"), 10),sample(seq(as.Date('2017/03/01'), as.Date('2017/09/01'), by="day"), 10),c(as.Date('2017/05/02'),sample(seq(as.Date('2017/05/01'), as.Date('2017/09/01'), by="day"), 9)),sample(seq(as.Date('2017/03/01'), as.Date('2017/09/01'), by="day"), 10),c(as.Date('2017/05/03'),sample(seq(as.Date('2017/05/01'), as.Date('2017/09/01'), by="day"), 9)))
)
将它分成3个相等的时间段看起来像:
library(lattice)
xyplot(Data$Y ~ Data$X,,
panel = function(x, y) {
panel.xyplot(x, y)
panel.abline(v=c(as.Date('2017/05/01'),as.Date('2017/07/01')))
})
在这种情况下,如果我将第一个时段定义为2017/03/01至2017/05/03,而不是2017/04/30,我将不会为C组和E组提供NA第一个时期,这就是我想要的。
所以我希望这3个时期是:
但是,这些时期的开始/结束可以灵活多达10天。有没有办法做到这一点,而不是视觉上看?
答案 0 :(得分:1)
由于我们可以移动两个边界,每个边界在10个单位的间隔内,因此有21x21 = 441个选项。这似乎小到暴力(或者这是一个简化的数据集,你的实际问题更大?)。
无论如何,这里有一些非常不理想的代码可以满足您的需求:
Data <- data.frame(
Y = c(rep("A",10),rep("B",10),rep("C",10),rep("D",10),rep("E",10)),
X = c(sample(seq(as.Date('2017/03/01'), as.Date('2017/09/01'), by="day"), 10),sample(seq(as.Date('2017/03/01'), as.Date('2017/09/01'), by="day"), 10),c(as.Date('2017/05/02'),sample(seq(as.Date('2017/05/01'), as.Date('2017/09/01'), by="day"), 9)),sample(seq(as.Date('2017/03/01'), as.Date('2017/09/01'), by="day"), 10),c(as.Date('2017/05/03'),sample(seq(as.Date('2017/05/01'), as.Date('2017/09/01'), by="day"), 9)))
)
split1 = as.Date('2017/05/01')
split2 = as.Date('2017/07/01')
library(dplyr)
argmin=[i,j]
minimum = 999
for(i in seq(-10,10))
{
for(j in seq(-10,10))
{
df = Data %>% group_by(Y) %>% summarize(period1 = sum(X<(split1+i)),
period2 = sum(X>=(split1+i) & X<(split2+j)),
period3 = sum(X>=(split2+j)))
if(sum(df==0)<minimum)
{
argmin = c(i,j)
minimum = sum(df==0)
}
}
}
cat(paste0("period 1: 2017-03-01 to ",split1+argmin[1]-1,"\n"))
cat(paste0("period 2: ",split1+argmin[1]," to ",split2+argmin[2]-1,"\n"))
cat(paste0("period 3: ",split2+argmin[2]," to 2017-09-30 \n"))
cat(paste0("Total NA's: ", minimum))
输出:
period 1: 2017-03-01 to 2017-05-03
period 2: 2017-05-04 to 2017-06-20
period 3: 2017-06-21 to 2017-09-30
Total NA's: 0