# Spline的內插求X值
###### tags: `Spline`, `R`
> **R gui 4.1.2 version**
> **package:** splines
## :memo: Spline的內插求值
### Step 1: 導入/建立數據
:::info
一般習慣使用package xlsx,導入excle裡面的資料。不過由於都是實驗資料,所以這邊先用一個假設的資料吧~~ 假設數據如下:
:::
| obs | x |y |
| --- | ------:| -----:|
| 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)
```
輸出結果

- 利用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")
```
輸出結果

- 決定好後用哪個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")
```
輸出結果

### 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) #我們把它畫到圖上看看吧
```
輸出結果

```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|
```
大功告成~