你是如何從紙上變成代碼的?
我的背景是計算生物學,儘管我是一名受過訓練的生物學家。我最近剛開始攻讀博士學位,雖然我對計算生物統計學/流行病學和方法開發有濃厚的興趣/好奇心,但我相當確定我不必開發和實施新方法。但正如我所說,我對此很好奇。
更準確地說,我仍然不明白有人如何從研究論文變成一個
R
包。我覺得這很困難,不僅因為我可能對它沒有正確的理論理解,還因為我發現編程統計方法特別困難。我知道如何編寫代碼,我編寫了相當多的代碼,但我從來不需要從介紹它的論文開始實現一個方法。舉個例子,我最近看到了這篇論文,顯然有人在
R
這裡實現了它(文件名為focus_1.0.0.tar.gz
)。我真的不知道從哪裡開始。你需要什麼樣的心智模型才能將這樣的框架翻譯成代碼?
更準確地說,我仍然不明白有人如何從研究論文轉到例如 R 包。
就像生活中的很多事情一樣,有時最困難的部分才剛剛開始。很多人為失敗做好了準備,只是,好吧,認為他們沒有做好足夠的準備並且會失敗,所以他們甚至在嘗試之前就已經放棄了。
話雖如此,你必須至少知道一點才能開始。在基於論文編寫 R 包的上下文中,您不一定需要熟悉該主題背後的數學或理論才能開始。您可能會發現編寫包的過程實際上有助於加深您最終想要擁有的理解,並且隨著時間的推移,您將對反映這一點的包進行更改。實際上,我有一個非常健壯、用戶友好的 R 包,我就是在這種情況下開始的。我有很多編程經驗,我認識的一個人有他一直在開發的這個不平凡的理論,但沒有能力在一個包中正確實現,所以他讓我幫忙。數學和理論的細節對我來說大多是陌生的,因為我的專長在其他地方。我沒有' 那時甚至不知道創建 R 包的細節。但是現在,在完成了創建包的過程之後,我什至能夠對理論及其應用做出自己的貢獻和進步。
首先,您需要做的是考慮用戶可能想要的包中的內容。這篇論文提出了哪些潛在用戶會發現有用的信息?這確實需要至少對論文完成的內容有一個高層次的理解;大概,如果您不知道論文的內容,您就不會嘗試為論文編寫包。因此,列出用戶想要的東西。現在將這些項目分配給函數名稱,而不用擔心這些函數內部如何工作的細節。例如,您可能有一個執行核心統計分析的函數,一個計算置信區間的函數,一個計算方差的函數,還有一個執行基本可視化的函數。
接下來,這些功能需要哪些最基本的輸入?可能有很多小東西對功能的便利性、調整或靈活性有用,但這些還不重要。重要的是讓基本功能運行起來;您可以稍後返回並處理更精細的細節,以免它們現在讓您不知所措。
現在,這些函數返回的值是什麼?換句話說,用戶期望或發現在結果方面最有用的是什麼?其中一部分可能最終會被前面關於輸入的觀點塑造或塑造。如果你有一個函數建立在另一個函數的結果之上,那麼一個函數的輸入將成為另一個函數的輸出。因此,根據具體情況,您可能有一個函數返回簡單的東西,如數字或向量,而您可能有另一個函數返回複雜的東西,如列表或類對象。
一旦你有了一個你想要的函數列表,它們需要什麼輸入,以及它們產生什麼,你現在就擁有了一個基本骨架包所需的東西。因此,通過創建一堆空函數開始編碼。或者也許只是讓他們打印一些東西。如果您以前從未編寫過軟件包,那麼現在是嘗試構建和安裝它(在您的計算機上本地)以確保它工作的好時機。在您工作時,定期構建、安裝、加載和測試您的包,以確保一切都按照您的想法進行。
最後,通過骨架包設置,您現在可以開始深入研究數學/理論細節。你的函數可以作為指導來幫助你分解這個任務,這樣你就不會試圖通過一次專注於所有事情來壓倒自己。只專注於一件事,並努力讓函數的基礎知識運行起來。此時您絕對不應該擔心性能。其他事情也一樣,比如帶有輸入數據的奇怪的極端情況。您應該專注於以盡可能簡單的方式實現事物。一旦一切都在運行並且您對一切都有更好的感覺,那麼您就可以重新訪問。
最終,您將更深入地了解您正在嘗試使用您的包完成什麼。您可能會發現自己意識到您需要一些以前沒有想到的功能,或者可能需要組合您的幾個功能。你甚至可能回過頭來意識到有一種完全不同的做事方式更好。對於我的包,v0.1.0(本質上是一個測試版)和 v1.0.0(第一個生產版本)是不同的。我從頭開始完全重寫了 v1.0.0 的包。v0.1.0 非常適合學習,不僅是數學和理論,還有我的框架決策作為用戶和包維護者的感受。事實證明,這對雙方來說都是笨重且令人不快的,並且值得投資進行全面檢修。所以不要擔心馬上讓它變得完美;花點時間在預發布階段進行嘗試,最好讓一些潛在用戶有機會嘗試並提供反饋。我無法告訴你其他人的真實世界數據多久會暴露你從未考慮過的奇怪的極端情況……
一些額外的提示:
- 技術債務:有時會有多種方式來完成一項任務。在發布您的包之前,您需要提前考慮這些選擇的含義,因為如果您只是採取簡單的方法,您可能會發現以後要花費大量時間來解決問題。最好在發布之前處理好這一點,因為您希望避免在用戶開始使用包後破壞他們的東西。有大量關於“技術債務”的文章。花一些時間閱讀其中的一些。
- 維護負擔:如果你打算創建一個 R 包,請致力於維護它。我在科學軟件中看到的一個大問題是,許多人將軟件/軟件包作為出版物的一次性任務發布,然後讓它腐爛,當軟件出現問題時,這最終會花費其他人大量的時間和精力為他們。希望你不是其中之一。為此,您必須了解您在設計包裝時的選擇將如何影響您以後的時間承諾。您添加的每一件小事都是一件可能會破壞的事情,需要進行測試,需要對用戶的支持等,從而導致花費更多時間來維護您的包,而不是您想做的其他事情。因此,請謹慎對待添加的內容和從功能列表中刪除的內容;如果您嘗試添加人們想要的每一個方便的小東西,那麼您以後會後悔的。考慮你的包需要哪些外部包也是如此;您添加的每個依賴項都是另一個人在他們的包中進行的更改以破壞您的包的機會。
- 要發布 R 包,請將其放在 CRAN 上。我無法告訴你有多少次我查看了非 CRAN 包的 GitHub 存儲庫(帶有經過同行評審的出版物),只是為了發現 CRAN 的“煩人”政策可以防止的基本缺陷。說真的,我查看的一個包改變了許多其他常見包隱式依賴的多個默認 R 行為。只需加載包,它就可以完全改變其他包的行為,這種方式完全靜默,結果變化不明顯,並且只能通過重新啟動 R 輕鬆修復(並且永遠不會再次加載包)。CRAN 包中明確禁止此包用於執行此操作的命令。如果作者試圖發佈到 CRAN,他們會抓住它(或者他們確實嘗試過並決定它不是
- 使用自動化測試(對於 R,請參閱“testthat”包)。這確實應該是任何軟件包的要求。不幸的是,僅僅因為一個包有單元測試並不意味著它做得很好。弄清楚如何做好它可能是一種藝術形式。
- 良好的文檔是必要的。而且我不僅僅指典型的 R 函數引用。我希望大多數人都能從各種解釋概念和舉例的教程/小插曲中受益。嘗試寫這些實際上將有助於您自己對數學和理論的理解,或者至少讓您對所學內容充滿信心。對於 R,我建議為此查看“pkgdown”包;它可以幫助您為您的包構建一個網站,該網站作為包的 GitHub 存儲庫的一部分託管。
一些告別的話:如果您要為科學家編寫軟件,請記住責任的重要性。如果你真的全身心投入並且做對了,你可以對許多人更有效地進行研究的能力產生巨大的影響。但是,如果你半途而廢或懶於維護它,你可能會搞砸很多人,並花費他們大量的時間、精力和潛在的金錢。無論哪種方式,你都有可能對科學產生巨大的影響,而你通常只呆在你自己的小研究泡沫中就可能不會產生這種影響。