零基礎版。只要會開 R、會按 Source,就能跟著做完。 先讓你在 5 分鐘內跑出一張「對位前 vs 對位後」的圖,再用白話解釋每一步在做什麼。 完全不需要先懂小波或最佳化演算法。
同一台儀器、同一個方法,不同時間跑出來的層析圖, 波峰位置會偏移。alignDE 把它們推回同一個位置。
為什麼會偏移?管柱溫度變了、流動相配得略有不同、幫浦壓力有波動、管柱用久了…… 這些都會讓同一個化合物今天在 5.38 分鐘出來,明天變成 5.29 分鐘。
拿本專案的真實資料舉例:上午跑的樣品,整條層析圖比下午跑的標準品往左偏了 0.083 分鐘。 看起來很小,但已經足以讓儀器軟體的自動判峰失效。
右圖樣品的兩個峰,都明顯落在虛線的左邊——這就是偏移。
alignDE 沒有上 CRAN,所以不能用 install.packages("alignDE")。
本專案使用的版本已發布在 GitHub(Tai-ShengYeh/alignDE),用 remotes 套件安裝即可。
install.packages(c("DEoptim", "Matrix", "remotes"))
remotes::install_github("Tai-ShengYeh/alignDE")
packageVersion("alignDE")
#> [1] '3.0.1'
# 想知道裝在哪個資料夾:
find.package("alignDE")
zmzhang/alignDE,版本是 2.0.1(2012 年),
不是本專案需要的版本。如果你不小心執行
remotes::install_github("zmzhang/alignDE"),
裝到的會是 14 年前的舊版——
那個版本內建自己的差分演化實作(慢 1~2 個數量級)、
函式介面也不同,本專案的腳本會跑不起來。
請務必安裝 Tai-ShengYeh/alignDE(v3.0.1)。cat("版本:", as.character(packageVersion("alignDE")), "\n")
cat("位置:", find.package("alignDE"), "\n")
兩者都應該顯示 3.0.1,且路徑指向 R 套件庫(GitHub 安裝不會留在本機資料夾)。
如果版本比較舊,先移除再重裝:
remove.packages("alignDE")
remotes::install_github("Tai-ShengYeh/alignDE")vignette("alignDE-basic", package = "alignDE") # 基礎
vignette("alignDE-advanced", package = "alignDE") # 進階
browseVignettes("alignDE") # 全部列出
本專案附了一支最小範例 alignDE_quickstart.R。
它只做一件事:把一張偏移的層析圖對回參考圖,印出改善的數字、畫一張前後對照圖。
# RStudio:開啟 alignDE_quickstart.R,按右上角 Source
# 終端機:
Rscript alignDE_quickstart.R
# R 主控台:
source("alignDE_quickstart.R")
使用中的 alignDE 版本: 3.0.1
參考圖找到的峰 (min): 5.375 5.925
樣品圖找到的峰 (min): 5.292 5.842
→ 兩者相差約 -0.083 分鐘,這就是要修的漂移
對位前 相似度 = 0.5081
對位後 相似度 = 0.8695 (改善 +0.3614)
相似度就是「這張圖和參考圖有多像」,範圍 0 到 1,越接近 1 越像。 從 0.51 提升到 0.87,代表對位成功了。
峰的高度不會變,只有位置被移動——這是 alignDE 最重要的特性。
快速上手的那 30 行程式碼,其實就是這五步。這裡完全不用公式解釋一遍。
下圖的兩個色塊如果套在上圖,會切到很多峰的一半——這就是不對位不行的原因。
濃度越高,填色的面積越大——這就是檢量線的基礎。
紅點(本流程自己積分的)和藍圈(儀器軟體算的)幾乎重合,代表積分是對的。
看程式碼和文件時會遇到的詞,一句話講完。
參數看起來很多,但初學者其實只需要關心三個。按這個順序調:
slack(允許平移的最大點數)這是唯一一定要按你的資料調的參數。做法:看兩張圖同一個峰差了多少分鐘, 除以取樣間隔,再留一點餘裕。
# 本專案:偏移 0.083 分鐘,取樣間隔 0.00833 分鐘
0.083 / 0.00833 # ≈ 10 個點 → slack 設 25 就很夠
slack 設太小 → 峰推不到位,對位失敗。
設太大 → 搜尋範圍變大、變慢,而且有機會把 A 峰錯推到 B 峰的位置。
寧可略大,但不要大到超過兩個峰的間距。SNR.Th(訊噪比門檻)決定「多小的峰還算峰」。找不到峰就調低、抓到太多雜訊就調高。
SNR.Th = 3 # 保守,只抓明顯的峰(預設建議值)
SNR.Th = 1 # 本專案用這個,才抓得到比較小的己二烯酸峰
SNR.Th = 0 # 幾乎全抓,會混進雜訊,不建議
不要把整條層析圖丟進去。只取你關心的峰所在的區間, 把注射時的溶劑大擾動排除掉。本專案取 4.5~7.0 分鐘。
| 參數 | 預設 / 本例 | 什麼時候才需要動 |
|---|---|---|
scales | 1:31 | 峰特別寬或特別窄時。上限受資料長度限制(見錯誤排解) |
ridgeLength | 5 | 幾乎不用動。5~10 之間 |
lambda(基線) | 100 | 基線明顯彎曲時可以加大;但太大會出問題(見下) |
n(peakClustering) | 5 | 峰擠在一起時可以調小 |
NP / itermax | 60 / 150 | 對位結果不穩定時把兩者加大 |
lambda 不要設太大。
本專案實測:λ 從 100 加到 10000,基線被過度平滑成一條水平線,
無視旁邊大峰的拖尾,結果把拖尾也當成小峰的訊號積進去,
讓一個微量結果從 0.60 ppm 虛胖到 0.91 ppm。那是假訊號,不是量得比較準。點開看解法。這些都是實際跑這個專案時遇到過的。
Error in cwt(...) : scale 32 is too large!
原因:小波的尺度不能超過訊號長度的一定比例。程式會先把資料補到 2 的次方長度, 墨西哥帽小波的最大可用尺度大約是補完長度 ÷ 16。
解法(挑一個):
# A. 把 scales 上限調小(最簡單)
scales = 1:31 # 301 點 → 補到 512 → 512/16 = 32,所以最大 31
# B. 把分析區間 (ROI) 取寬一點,讓資料點變多
keep <- rt >= 4.0 & rt <= 7.5
快速算法:floor(2^ceiling(log2(資料點數)) / 16) - 1 就是安全上限。
Error in alignDE(...) : 'peakWidth' contains no peak.
原因:這張圖一個峰都沒偵測到,所以沒東西可以對位。
解法:把 SNR.Th 調低(例如 3 → 1),或確認 ROI 有涵蓋到峰的位置。
先畫圖確認峰真的在你以為的地方:
plot(rt, mv, type = "l", xlim = c(4.5, 7.0))
原因:差分演化是隨機演算法,每次的起始族群不同。
解法:在呼叫 alignDE() 之前固定亂數種子。這是可重現分析的必要動作:
set.seed(1) # 任何數字都可以,重點是固定
aligned <- alignDE(...)
如果固定種子後差異還是很大,代表搜尋沒收斂,把 NP 和
itermax 加大(例如 100 / 300)。
不一定。相似度衡量的是「整條曲線的形狀」。 如果兩個樣品的成分本來就不同——例如一個只含苯甲酸、另一個只含己二烯酸—— 就算峰位置完全對齊了,相似度也到不了 1。
正確的判斷方式:畫圖看峰位置有沒有對齊,不要只看相似度的數字。
plot(RT, ref_sig, type = "l")
lines(RT, aligned, col = "red") # 峰對齊了就是成功
Error in library(alignDE) : there is no package called 'alignDE'
解法:回到第 2 節重裝。注意順序:先 DEoptim、Matrix、remotes,再 alignDE。
install.packages(c("DEoptim", "Matrix", "remotes"))
remotes::install_github("Tai-ShengYeh/alignDE")
packageVersion("alignDE") # 應該是 3.0.1
原因:幾乎都是因為裝到 zmzhang/alignDE(GitHub 上另一個舊 repo),
或 R 從別的 library 路徑載入了舊版。
# 看清楚裝了幾份、各是什麼版本
for (p in .libPaths()) {
d <- file.path(p, "alignDE")
if (dir.exists(d))
cat(d, "->", read.dcf(file.path(d, "DESCRIPTION"))[1, "Version"], "\n")
}
# 全部移除再重裝正確的版本
remove.packages("alignDE")
remotes::install_github("Tai-ShengYeh/alignDE")
原因:儀器匯出檔是 Big5 (CP950) 編碼,不是 UTF-8。
解法:本專案的 lcsolution_io.R 已經處理好了,直接用它的
get_chromatogram() 讀檔就不會有問題。
如果要自己讀,記得指定編碼:
con <- file("檔名.txt", encoding = "CP950")
lines <- readLines(con, warn = FALSE); close(con)
packageVersion("alignDE") 顯示 3.0.1alignDE_quickstart.R 跑得出來,相似度從 0.51 提升到 0.87quickstart_result.png 上下兩張圖的差別slack 要怎麼從自己的資料算出來set.seed() 才能重現把 alignDE_quickstart.R 開頭的兩個檔名換掉,再依第 6 節調三個參數即可:
REF_FILE <- "你的參考層析圖.txt"
SMP_FILE <- "你要對位的層析圖.txt"
如果你的檔案不是 Shimadzu LCsolution 匯出格式,就自己讀成兩個向量
(時間 rt 和訊號 mv)餵進去,其餘都不用改。
Rscript hplc_alignDE.R # 對位 + 積分 + 檢量線 + 定量,輸出 11 張圖
python build_teaching_html.py # 產生進階版教學網頁
| 文件 | 範圍 | 什麼時候讀 |
|---|---|---|
| teaching_beginner.html | HPLC 數據處理觀念:看懂層析圖、檢量線是什麼、怎麼判斷做得對不對、隨堂測驗 | 完全沒接觸過 HPLC |
| 本文 | alignDE 實際操作:安裝與版本確認、5 分鐘最小範例、名詞辭典、參數調整順序、錯誤訊息排解 | 要動手跑 alignDE |
| teaching_alignDE.html | 原理與驗證:CWT / Whittaker / 加權迴歸的推導、CWT 尺度圖與脊線、基線方法比較實驗、15 篇參考文獻 | 想知道為什麼這樣做有效 |
hplc_calib.R / hplc_calib.py,
直接採用儀器軟體算好的峰面積來建檢量線,不做對位與自行積分。
兩套流程的結果差異在 5% 以內,可以互相驗證。