2015-11-24 81 views
1

問題插值與樣條曲線,並保持精確的打結值

我與花鍵玩弄和嘗試連接月份中旬進行插值整個年開始,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 

圖片:

紅:原始月點

黑線:從樣條插值

回答

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 
+0

如果我理解你的問題,你可能會注意到,'df'可以包含任何一組日期(存儲爲R'Date'對象)和值那些日子被用作基礎插值包括多年。然後,您可以爲代碼中所示的時間間隔內的所有日期生成值向量,也可以直接使用'values_by_date'函數獲取任意日期集合的值。 – WaltS

+0

對不起,我誤解了你如何提出答案。這工作完美!謝謝 – Vedda

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) 

輸出:

Output

紅線表示自己的原始數據,而黑線是平滑的數據。

希望這有助於

+0

謝謝你的回答。這與@WaltS有什麼不同?你爲什麼認爲這種方法更好? – Vedda

+0

@Amstell它有點複雜,因爲它需要你手動提供每個月的長度......它避免了處理日期值(這經常讓我困惑),讓我們定義偏移量(你可以將數據放在一起本月任何一天通過更改'offset'變量) – Barranka

+0

好的謝謝。如果我必須在使用日期之外使用樣條線,我會堅持這一點。真棒回答! – Vedda