---
# System prepended metadata

title: Spline的內插求y值 (更新版_my first HackMD note)
tags: [Spline]

---

# 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| 
```

大功告成~