问题
我正在玩样条曲线,试图连接中期几个月,从1月15日开始插入整年;但是,我想确保全年正确设置中点月份。也就是说,在每个月我都希望中间点(第15个)与原始月度数据相同。目前,我的代码没有这样做,有些值与原始代码有很大不同。如果可能的话,我想确保那些确切的值适合每月中点(15日)的数据。
有没有办法确保原始数据中的这些点在插值数据中正确设置,以便它们位于每月中点(第15位)的确切位置?
示例:
# Monthly data
df <- data.frame(x <- seq(1,12),
y <- c(45, 54, 50 ,63, 70, 75, 80, 88, 76, 81, 63, 54))
# Interpolate with spline to daily data starting with 15th of January (351 days)
values <- spline(df$x, df$y, n = 351)$y
# Check values
# Original values
df$y
# New values at 15th of each month
values[c(1,31, 60,91,121,152,182,213,244,274,305,335)]
输出(有些圆形,但大多数已关闭):
> df$y
[1] 45 54 50 63 70 75 80 88 76 81 63 54
> values[c(1,31, 60,91,121,152,182,213,244,274,305,335)]
[1] 45.00000 54.21321 49.65891 60.61385 68.91151 73.89644 77.62606 87.33305 79.66860 79.27115 73.10543 54.71480
期望的输出:
> df$y
[1] 45 54 50 63 70 75 80 88 76 81 63 54
> values[c(1,31, 60,91,121,152,182,213,244,274,305,335)]
[1] 45 54 50 63 70 75 80 88 76 81 63 54
图片:
红色:原始月份
答案 0 :(得分:2)
如果您尝试将日历与日历日对齐,则可以让R执行跟踪日期的工作。这种方法也将照顾闰年。最后,您可以从1月15日开始按日编制索引。以今年为例,代码可能如下所示:
df <- data.frame(x=seq.Date(as.Date("2015-01-15"), by="month", length.out=12),
y = c(45, 54, 50 ,63, 70, 75, 80, 88, 76, 81, 63, 54))
values_by_date <- splinefun(df$x, df$y)
#
# To get a value at every day between Jan 15 and Dec 15
#
values <- values_by_date(seq.Date(df$x[1], tail(df$x,1), by="day"))
#
# Check dates at mid month
# Note that second index should be 32, not 31
#
values[c(1,32, 60,91,121,152,182,213,244,274,305,335)]
[1] 45 54 50 63 70 75 80 88 76 81 63 54
答案 1 :(得分:1)
也许它比WaltS提供的答案更复杂,但它确实有效:
# Input data:
df <- data.frame(x <- seq(1,12),
y <- c(45, 54, 50 ,63, 70, 75, 80, 88, 76, 81, 63, 54))
# I use this dataframe to get the right position for the ticks
# The "offset_days" column is left 'empty' at start:
days_of_month <- data.frame(months=c('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'),
days = c(31,28,31,30,31,30,31,31,30,31,30,31),
offset_days = 0)
# Offset: The day of month you want your ticks to be placed (should be between 1 and 28):
offset <- 15
# Fill the "offset_days" column with the appropriate day
for(i in 1:nrow(days_of_month)) {
if(i == 1)
days_of_month$offset_days[i] <- offset
else
days_of_month$offset_days[i] <- days_of_month$offset_days[i-1] + days_of_month$days[i-1]
}
# Calculate the spline with the offset days as x value:
sp <- spline(days_of_month$offset_days, df$y, 351)
plot(sp$x, sp$y, type='l', xlim=c(0,365), xaxt='n')
lines(days_of_month$offset_days, df$y, type='o', col='red')
axis(side=1, at=cumsum(days_of_month$days), lab=rep('',12))
axis(side=1, at=days_of_month$offset_days, lab=days_of_month$months, tck=0)
输出:
红线表示原始数据,黑线表示平滑数据。
希望这有帮助