# Spline的內插求X值 ###### tags: `Spline`, `R` > **R gui 4.1.2 version** > **package:** splines ## :memo: Spline的內插求值 ### Step 1: 導入/建立數據 :::info 一般習慣使用package xlsx,導入excle裡面的資料。不過由於都是實驗資料,所以這邊先用一個假設的資料吧~~ 假設數據如下: ::: | obs | x&emsp;|y&emsp;| | --- | ------:| -----:| | 1 | -1.50 | 0.00| | 2 | -0.50 | 0.06| | 3 | 0.50 | 0.09| | 4 | 1.63 | 0.41| | 5 | 2.75 | 14.97| | 6 | 3.63 | 51.58| | 7 | 7.50 | 100.00| - 輸入數據: ```r=1 #建立數據 mydata1<-data.frame( "x"=c(-1.50,-0.50,0.50,1.63,2.75,3.63,7.50), "y"=c(0.00,0.06,0.09,0.41,14.97,51.58,100.00)) mydata1 ``` - 如果要到導入資料則如下: ```r=1 #利用xlsx套件載入excel建立好的資料 #檔案位置/檔案名稱.xlsx,如 "D:/downlaod/A.xlsx" #如果檔案內有使用中文名稱,後來的版本都要加上encoding="UTF-8"才能順利讀取 library(xlsx) mydata1<-read.xlsx("檔案位置/檔案名稱.xlsx",sheetName="資料表名稱",stringsAsFactors=TRUE,encoding="UTF-8") ``` ### Step 2: 藉由繪圖找出所需的連接線line spline :::info 利用splinefun,運算不同的spline ::: - 可以先畫出原本資料的XY散佈圖,看看原貌 ```r=6 #attach資料,這樣就不用mydata1$x 或 mydata1$y 來呼叫所需 attach(mydata1) #繪製xy散佈圖,並先用灰色線連起來 plot(x,y) lines(x,y,col=8,lty=1,lwd=1.5) ``` 輸出結果 ![](https://hackmd.io/_uploads/ByRnNwUWp.png) - 利用splinefun,運算不同的spline的方法有: "fmm", "periodic", "natural", "hyman","monoH.FC",依圖形選擇合適的 ```r=11 F1 <- splinefun(x, y, method="hyman", ties ="ordered") F2 <- splinefun(x, y, method="monoH.FC", ties ="ordered") F3 <- splinefun(x, y, method="natural", ties =c("ordered",mean)) #加上spline的曲線 curve(F1,col=3,lty=2,lwd=1.5,add=TRUE) curve(F2,col=4,lty=3,lwd=1.5,add=TRUE) curve(F3,col=2,lty=4,lwd=1.5,add=TRUE) legend("topleft", legend = c("origanl", "spline hyman", "spline monoH.FC", "natural"), lty = 1:4, col = c(8,3,4,2), lwd = 2, bty = "n") ``` 輸出結果 ![](https://hackmd.io/_uploads/B1ATHvUZT.png) - 決定好後用哪個Fucntion後,利用smooth.spline的predict功能,反求預期的X值 ```r=22 #先畫一條通過選擇Fucntion的smooth.spline new_y<-F2(seq(-1.5,7.5,(7.5+1.5)/100)) new_x<-seq(-1.5,7.5,(7.5+1.5)/100) lines(smooth.spline(new_x,n_y),col="red") ``` 輸出結果 ![](https://hackmd.io/_uploads/S1MLUvUbT.png) ### Step 3: 選擇合適之spline求出x̂ :::info 在本例中,我選擇monoH.FC比較貼近原始線段(紅色實線標記)。或著也可以多做幾組數據後,再來抉擇選擇何種模式較妥。須符合常理及實驗假設為原則。 ::: 這裡假設希望知道在y=5,16,25,50,75,84,90,95時,所對應的x估計值 - ```r=26 #接下來,反求通過目標y的估計值x̂ (hat.x.) y5<-predict(smooth.spline(new_y,new_x),5)$y y16<-predict(smooth.spline(new_y,new_x),16)$y y25<-predict(smooth.spline(new_y,new_x),25)$y y50<-predict(smooth.spline(new_y,new_x),50)$y y75<-predict(smooth.spline(new_y,new_x),75)$y y84<-predict(smooth.spline(new_y,new_x),84)$y y90<-predict(smooth.spline(new_y,new_x),90)$y y95<-predict(smooth.spline(new_y,new_x),95)$y groupnew_y<-c(5,16,25,50,75,84,90,95) #這是我想要的y值 hat.x.<-c(y5,y16,y25,y50,y75,y84,y90,y95) #這是求出來的x值 points(hat.x.,groupnew_y,col=2,pch=2,lwd=5) #我們把它畫到圖上看看吧 ``` 輸出結果 ![](https://hackmd.io/_uploads/SkipYD8Zp.png) ```r=26 outdata<-data.frame("new y"=groupnew_y,"hat(x)"=hat.x.) outdata#把結果輸出看看 #確認好了,把資料輸出成EXCLE檔案中吧 write.csv(outdata, file="路徑名稱/檔案名稱.csv"), row.names = FALSE) ``` | | new.y| hat.x.| |---| --- | --- | | 1 | 5| 2.266492| | 2 | 16| 2.784300| | 3 | 25| 3.015392| | 4 | 50| 3.577996| | 5 | 75| 4.837420| | 6 | 84| 5.700876| | 7 | 90| 6.465014| | 8 | 95| 7.045637| ``` 大功告成~