從另一個視角看 R 語言的「方言」 Tidyverse,以及 RStudio 對 Tidyverse 的提倡。
作者簡介作者 Norm Matloff 為 UC Davis 計算機科學教授(曾任 UCD 統計學教授)。中文翻譯及投稿至 COS 經過作者同意[1]。文中的「我」為作者視角,但譯文中存在的任何不妥之處當然很可能是由譯者引入的,還望讀者不吝賜教[2]。
注意:此為簡版在我看來,Tidyverse 的主要問題在於其不利於教學。我相信使用 Tidyverse 而非 base-R 實際上會阻礙對沒有編寫代碼背景的初學者進行教學。這個簡潔的版本僅保留了 TidyverseSkeptic 文中關於教學的部分。我在完整的文檔中還談及了其它問題,詳見英文原文全文[3]。
聲明本文在某種程度上比較坦率,並且涉及非常流行的 Tidyverse 及 RStudio。我想本文是有禮貌的,並且應被視為具有建設性的批評。
我對 RStudio 的人們抱有喜愛和尊敬的態度,包括 Tidyverse 的提出者 Hadley Wickham。我也一直支持他們,無論私下或是公開[4]。從公司只有創始人 JJ Allaire 和首席開發 Joe Cheng 的時候開始,我們就一直互動。我向我的學生們高度讚揚 RStudio 公司,我使用並推薦 Hadley 的包 ggplot2 和 stringr (均不屬於 Tidyverse),有時 devtools 確實節省了我大量時間。
換句話說,我並沒有把 RStudio 當作什麼邪惡社團。我在本文中的不少地方都表明我認為他們的行為具有良好的意圖。然而,我持有如下看法:決定推廣 Tidyverse 是 RStudio 作出的錯誤抉擇,這使 R 語言的一致性和健康性遭到威脅。
這裡是我的簡歷。[5] 關於 R 語言的部分,我從幾乎最開始就是 R 的用戶和開發者,在那之前我使用 R 的前身 S。我出版過幾本使用 R 語言的書,還擔任過 R Journal 的主編。Hadley 也曾任此期刊的主編。
可教學性概覽•我最大的擔憂來自 R 語言教學。對於需要學習 R 語言的非程式設計師來說,Tidy 讓精通這門語言變得更困難。
•Tidyverse 來自這樣一種渴求,即要有一組相互兼容、行為一致的函數或包。這種「純正」哲學對計算機科學家有著難以抗拒的吸引力。Tidyverse 也借鑑了其它「純正」計算機科學(Computer Science,以下簡稱 CS)哲學,特別是 函數式編程(Functional Programming,以下簡稱 FP)。FP 抽象化且理論化,即使對 CS 專業的學生來說也較困難。因此,顯然 若學習 R 語言的人並非程式設計師,Tidy 是一種不甚明智的方案。
•純正帶來的其它代價包括更複雜和更抽象,代碼更容易出錯(同時還犧牲了性能)。
•實際上,如果學習者之前沒有編寫代碼的背景,Tidyverse 總體來說過於複雜,這會引發心理學家所稱的 認知過載 現象。
•確實,很多 Tidy 的倡導者也承認在各種意義下 Tidy 代碼比 base-R 更難編寫。比如,Hadley 說「可能需要一些時間讓你的頭腦適應 [FP].」
•RStudio 提倡 Tidyverse 的時候聲稱它能夠使非程式設計師更容易學習 R。出於上述原因,與之正相反,我要提出異議:Tidyverse 讓這個群體的人們學 R 變得 更難。
•RStudio 作了可敬的工作,讓更多女性及未被充分代表的少數群體能接觸到 R。然而,由於被限制在複雜的 Tidyverse 系統中,這些群體將很難為 R 語言作出更多貢獻,諸如編寫 CRAN 包、撰寫書籍等等。這些工作需要相當熟悉 base-R 的使用,即使代碼本身仍然可以主要由 Tidyverse 寫就。當然,也不只是這些群體,這對任何人都適用。可惜的是 RStudio 正在傷害它本想要幫助的那些人。
可教學性從大學以來,教學一直是我興趣所在。我成為統計和計算機老師很多年,也得過一些教學獎項。我寫的課本 Statistical Regression and Classification: from Linear Models to Machine Learning 獲得 2017 年的 Ziegel Award。
除此以外,我對人們如何學習有濃厚的興趣,無論他們是孩童還是中年人。除了上述課程以外,我還教過移民成年人作為第二語言的英語,他們大多數沒有完成高中教育。
關於教學的討論,我這裡把對象定為 想用 R 進行數據分析的非程式設計師,而不是想成為專業 R 語言程式設計師的人。
案例分析:R 語言第一課Tidyverse 對初學者過於複雜。這裡有一些便捷的例子顯示 Tidy 的複雜性及其後果,非程式設計師學生學習 R 的時候難以適應。
來看一下我的在線 R 教程 fasteR[6]。比如,考慮下面一行
即用 R 內置的尼羅河數據集繪製一副簡單的直方圖。
這就是我教程的第一課。簡單!相反,用 Tidy 的群體不使用 base-R 而堅持使用 ggplot2 繪圖(再說一次,其實這並不屬於 Tidy,只不過有 Tidy 的倡導者常如此描述)。要想用 Tidy,老師需要如下操作
> library(ggplot2)> dn <- data.frame(Nile)> ggplot(dn) + geom_histogram(aes(Nile))如此,老師有太多東西需要解釋——包、數據框、ggplot()、aes 參數、+ 的作用(在這裡並不表示加法)等等——因此老師也許本不該在第一堂課就展示這種用法。
同樣出自我的第一課,還有
列印給定年份區間內尼羅河流量的平均數。令人驚奇的是,這不僅不會出現在 Tidy 第一課,使用 Tidy 教程的學生甚至有可能 永遠不會 學到如何做這件事。典型的 Tidy 老師並不認為向量對學習者有多麼重要,更不要說向量下標了。
作為這個 Tidy 觀點的實例,請見 Getting Started with R,作者 Beckerman et al,Oxford University Press,second edition,2017。這本書特別強調 「遵循 Tidyverse」[7]。書共231頁,僅簡略地提到向量,並且完全沒有提及下標。
案例分析:Dalgaard 的書2019年12月,一位研究者發推特說 Peter Dalgaard 的一本講統計學概論的書「過時了」,因為用的是 base-R 而非 Tidy。想一想如果要更新到 Tidy 會涉及什麼,又會強加給學生多少複雜性。這裡是書中的一個例子:
> thue2 <- subset(thuesen, blood.glucose < 7)基於 base-R 的話,這第二課可以輕鬆講到,說不定第一課就可以。而 Tidy 則不然,需要更改成
> library(dplyr)> thue2 <- thuesen %>% filter(blood.glucose < 7)老師首先要講授管道操作符 %>%,又一份額外的複雜性。在做這件事情的時候,老師很可能要強調管道是「從左到右」的流,然而學生會感到困惑,因為從左到右的流完成後,馬上就又跟著一個從右到左的流 <-。(不管出於什麼原因,Tidy 似乎並不使用 R 的 -> 操作。)
又一次,Tidyverse 對於沒有編程背景的學習 R 的人依然過於複雜,拖慢了學習進度。
Tidyverse 倡導者們的提法懷著為教學致力終生的熱情,我強烈質疑 Tidyverse 倡導者們的提法,即使用 Tidy 對非程式設計師進行教學,而不使用 base-R。
(我認為 dplyr 和 data.table 都是高階的課題;兩者都不適合初學者。另一方面,指導初學者使用 ggplot2 則完全可行,當然要再次指出其並不是 Tidyverse 的一部分)
還沒有關於倡導者們對 Tidy 可教學性的提法的研究。倡導者們通常會提供來自學生的讚譽,如
•「我用 Tidyverse 學習了 R,現在用 R 很有生產力」
•「我喜歡 Tidyverse 類似英文的自然用法」
•「我可以用 Tidyverse 做出漂亮的圖」
•「Tidyverse 向我展現了數據的流動」
同時也是老師的倡導者們則會重複這些陳述並加以評論,諸如:
•「Base-R 適合專業程式設計師,但 Tidyverse 是只想進行數據分析的非技術人員學習 R 的最佳工具」
•「R 由統計學家創造,為統計學家使用。而我們是數據科學家,主要興趣在於製作圖表」
•「Tidyverse 是 現代的 R,供我們其他人使用」
全部這些陳述要麼具有誤導性,要麼和可教學性問題無關,或者是徹底的空話。關於 base-R 與 Tidy 間可教學性的比較,它們等於什麼也沒有講。(諷刺的是,展示這些陳述的倡導者們是數據科學家,本應知道存在控制組的必要性。)
Tidyverse 帶來過多複雜性,讓學習變得更難與 Tidy 倡導者的提法正相反,我相信 Tidyverse 讓之前沒有編程背景的人更 難 學習。
認知過載是很嚴重的問題。Tidyverse 的學生要學習的材料相對多得多,這顯然不是好的教育方法。在「Tidyverse 詛咒」[8]一文中,作者提到 此外 他還「僅僅」用到了 60 個Tidyverse 函數——60!Tidyverse 的「明星」 dplyr 包含了 263 個函數。
儘管用戶最開始只需要用到這些函數的一小部分,高度的複雜性依然明顯存在。每當用戶要使用一個操作的某種變體,都必須從幾百個函數中篩選出正好是需要的那一個。
Tidy 倡導者說全部函數界面的統一性使學習變得更容易。統一的 語法 確實很好,但是實際情況是用戶真正需要學習的是函數的 語義,即每個函數將進行何種操作。舉例來說,summarize()、summarize_each()、summarize_at() 及 summarize_if() 區別何在?在何種情況下應該使用哪個函數?用戶必須加以篩選。
關於 dplyr,data.table 的創造者 Matt Dowle 指出[9]
你要整合進管道的並不是一個函數 mutate。這一個函數可以是 mutate、mutate_、mutate_all、mutate_at、mutate_each、 mutate_each_、mutate_if、transmute、transmute_、 transmute_all、transmute_at 或 transmute_if。而你卻告訴我 [因為用戶界面都是一致的] 不需要參考手冊就能學會這全部?只是共用一套語法,並不能減輕讓人昏頭的複雜程度。
作為對比,只要用戶學會了 base-R (不難),就可以用少數幾個簡單的操作處理各種情況。古話說得好:「授人以魚,不如授人以漁。」
Tidy 推廣者不希望 R 初學者學習什麼Tidy 推廣者提出避免使用 base-R 最基礎的部分:
•$ 操作符
•[[ ]]
•循環
•plot() 以及相關的基礎圖形函數等
他們聲稱這能「簡化」學習的過程,然而實際上卻會迫使初學者採用一套更複雜、不直觀且難以閱讀的方案。
案例分析:tapply() 函數tapply() 是在 R 語言裡最常使用的函數之一。如下所示,可以說它是對 R 初學者來說最好用的函數,但出於某些原因,Tidy 倡導者並不喜歡這個函數。
考慮 Tidyverse 教程裡一個常見的例子,用到 R 的 mtcars 數據集。目標是找出一部車消耗每加侖燃料平均能行駛多少英裡(miles per gallon, mpg),並按汽缸個數進行分組。Tidy 給出的代碼為
library(dplyr)mtcars %>% group_by(cyl) %>% summarize(mean(mpg))這是 base-R 版本:
tapply(mtcars$mpg, mtcars$cyl, mean)兩者都很簡單。都不難為初學者所掌握。初學者看過幾個例子後,把它們應用在同類別的新問題也不會有什麼困難。Tidy 版本調用了兩個函數,base-R 則是一個。無論如何,兩個版本都不複雜,難分伯仲。但是這當然不能算作 Tidy 版本比較 容易 學習的例子。
如何從兩個方面進行分組比較有指導意義:
> mtcars %>%+ group_by(cyl, gear) %>%+ summarize(mean(mpg))# A tibble: 8 x 3# Groups: cyl [3] cyl gear `mean(mpg)` <dbl> <dbl> <dbl>1 4 3 21.52 4 4 26.93 4 5 28.24 6 3 19.85 6 4 19.86 6 5 19.77 8 3 15.08 8 5 15.4> tapply(mtcars$mpg, list(mtcars$cyl, mtcars$gear), mean) 3 4 54 21.50 26.925 28.26 19.75 19.750 19.78 15.05 NA 15.4必須告訴學生,tapply() 用於分組的變量數多於一個時,要把變量用 list() 括起來。和前面一樣,只要有一些例子,學生們這樣用沒有什麼困難。
不過要看看輸出形式:Tidy 版本輸出一個 tibble,不易閱讀,而 tapply() 輸出一個 R 矩陣,以雙向表的形式列印出來。後者的形式恰好是很多學生所需要的,比如應用到社會科學研究等。
檢索過 dplyr 的幾百個函數後,我沒有找到如何把 Tidy 的輸出轉換為 tapply() 提供的更有信息量的表格樣式。就算這樣的函數存在,其難以被輕易識別也正好能體現我上述觀點,Tidy 過於臃腫,不適合初學者。
此外,tapply() 的輸出還有另一重含義,讓用戶能夠察覺沒有8-汽缸、4-擋位的汽車也是在很多應用中非常有意義的一類信息。
實際上,可以對 Tidy 版本加以修改以顯示空白組:
> mtcars$cyl <- as.factor(mtcars$cyl)> mtcars$gear <- as.factor(mtcars$gear)> mtcars %>%+ group_by(cyl, gear, .drop=FALSE) %>%+ summarize(mean(mpg))# A tibble: 9 x 3# Groups: cyl [3] cyl gear `mean(mpg)` <fct> <fct> <dbl>1 4 3 21.52 4 4 26.93 4 5 28.24 6 3 19.85 6 4 19.86 6 5 19.77 8 3 15.08 8 4 NaN9 8 5 15.4注意需要格式轉換,Tidy 文檔沒有提到。即使有文檔,這對 R 初學者來說也是更加複雜了。
因此,說到曉暢程度和可學習性,在這個特定的例子裡 Tidy 和 base-R 都不錯,Tidy 也並沒有更容易學習。至於可用性,我判 base-R 獲勝。
對函數式編程的使用Tidyverse 包中另一個特殊的庫,面向 函數式編程(FP)的 purrr,有 177 個函數。關於複雜性的論點依然適用;我們再次遇到和上述 dplyr 同樣的問題,「有太多函數要學」。
從入門的層次看,FP 就是調用 FP 函數以取代循環。R 的 apply 函數家族,再加上 Reduce()、Map() 和 Filter(),就屬於 FP。在很多情況下,使用這些函數是正確的方案。但是按很多 Tidy 推廣者提倡的,不加區分地使用 FP 替代 所有 循環,明顯是過分了,還特別給初學者帶來很多困難。
這個推斷是 先驗 的——FP 涉及函數的編寫,而多數初學者需要很長時間去掌握這項技能。
值得注意的是,頂尖大學的計算機系在逐漸調整編程緒論課程,不再使用 FP 範式,而是採用更傳統的 Python。他們認為 FP 更加抽象,更有挑戰性。
關於這個話題,一個有趣的討論見 Charavarty 和 Keller[10]。其實他們支持在 CS 專業的編程緒論課堂中使用 FP,但兩位作者的目標和學習 R 的人正好是對立的。作者們列出了三個目標,其中一個是講授計算機科學理論,對 R 的一般性教學來說,這是不可取的,更不要說教沒有編寫代碼經驗的人學習 R 語言。他們承認,即使是對 CS 學生來說,FP 的一個關鍵概念 遞歸 也是「顯著的障礙」。
如果說 FP 對 CS 學生就很難,那麼就沒有道理讓學習 R 的非程式設計師學生去使用 FP。
甚至 Hadley 也在 R for Data Science 中說道:
把一個函數傳遞給另一個函數,這個想法十分強大, 也是使 R 可以成為函數式程式語言的行為之一。你可能需要一些時間讓你的頭腦適應這個想法, 然而這種投入是值得的。實際上,大多數非 FP 的語言也允許將一個函數傳遞給另一個,而且這也確實是個強大的工具,值得投入時間學習——對於有經驗的 R 程式設計師來說。然而,不應當強迫學習 R 的非程式設計師「讓他們的頭腦適應」 purrr。
purrr 與 base-R 的對比我們再次使用 mtcars 做例子,來自在線教程[11]。這裡的目標是用車重去回歸英裡每加侖,計算每個汽缸組別的 R2。這是 Tidy 方案,來自 map() 的在線幫助頁面:
library(purrr)mtcars %>% split(.$cyl) %>% map(~ lm(mpg ~ wt, data = .)) %>% map(summary) %>% map_dbl("r.squared")# output4 6 80.5086326 0.4645102 0.4229655這裡有幾個主要的點需要注意:
•針對這個特定的例子,學習 R 的人必須要學習兩個不同的 map 函數,以及大量其它函數,只為了一個基礎用法。這個例子很好地說明了 Tidy 認知過載的問題。實際上,purrr 有 52 個不同的 map 函數!(見下)
•第一個 map 調用中的第一個 ~ 十分不直觀,即使有經驗的程式設計師也沒法猜出其作用。這能有力反駁 Tidy 倡導者所聲稱 Tidy 更符合直覺、就像英語。
•Tidy 執著於避開使用 R 語言標準的 $ 符號,導致了各種混亂與困惑。
•不幸的學生自然要問:「表達式裡的 『summary』 是哪裡來的?」看起來像是在調用 map() 的時候用了不存在的變量 summary。而在幕布背後,實際上是 base-R 的 summary() 函數被調用於前面的計算。這又是相當不直觀的,在線幫助頁面中也 沒有 提到。
•這個可憐的學生會對調用 map_dbl() 感到進一步困擾。那個 r.squared 從哪裡來?再一次,Tidy 把事實隱藏了,summary() 會產生一個含有 r.squared 組件的 S3 對象。是的,有時候隱藏細節是有幫助的,但只是在不會讓初學者感到困惑的時候。
實際上,R 初學者最好還是從寫一個循環開始,避開具有挑戰性的 FP 概念。即使老師認為初學者 必須 學習 FP,base-R 版本也要簡單很多:
lmr2 <- function(mtcSubset) { lmout <- lm(mpg ~ wt, data=mtcSubset) summary(lmout)$r.squared}u <- split(mtcars, mtcars$cyl)sapply(u, lmr2)這裡 lmr2() 有明確的定義,而不是 Tidy 版本裡難以看透的 map() 調用和其中的 ~。
在關於這個例子的推特討論[12]中,一個 Tidy 倡導者提出異議說上面的 purrr 代碼不適合學生用:
說的沒錯,但我原本的推特是講如何教導新人的。你的例子其實是無關的,因為這是非常複雜的概念。這就是我的觀點!新人應該用循環,而不是purrr。然而 Tidy 推廣者不願讓學生用循環。所以用 Tidy 的老師就得避免給學生用這樣的例子,對於同樣的例子,用 base-R 的老師就很容易處理。
如上所述,Tidy 版本是對「有太多函數要學」這種認知過載的寫照,我們更早在 dplyr 中也見到了這個問題。請看:
> ls('package:purrr', pattern='map*') [1] "as_mapper" "imap" "imap_chr" "imap_dbl" [5] "imap_dfc" "imap_dfr" "imap_int" "imap_lgl" [9] "imap_raw" "invoke_map" "invoke_map_chr" "invoke_map_dbl"[13] "invoke_map_df" "invoke_map_dfc" "invoke_map_dfr" "invoke_map_int"[17] "invoke_map_lgl" "invoke_map_raw" "lmap" "lmap_at" [21] "lmap_if" "map" "map_at" "map_call" [25] "map_chr" "map_dbl" "map_depth" "map_df" [29] "map_dfc" "map_dfr" "map_if" "map_int" [33] "map_lgl" "map_raw" "map2" "map2_chr" [37] "map2_dbl" "map2_df" "map2_dfc" "map2_dfr" [41] "map2_int" "map2_lgl" "map2_raw" "pmap" [45] "pmap_chr" "pmap_dbl" "pmap_df" "pmap_dfc" [49] "pmap_dfr" "pmap_int" "pmap_lgl" "pmap_raw"作為對比,base-R 版本中我們就只用到了 base-R!在 apply 家族中只有四個函數要學:apply()、lapply()、sapply() 和 tapply()。
Tibbles同樣,迫使學生學習 tibbles 是糟糕的教學方法。這是更複雜的技術,還是數據框更簡明。需要 tibbles 解決的情況應屬於進階課題,並不適宜沒有編碼背景的初學者。
這些高級的情況下,數據框裡列或行的元素不是 原子 對象,即並非簡單的數字、字符串或者邏輯值。這是 Tidy 倡導者樹立的「稻草人」;R 初學者不大可能遇到這種類型的數據框。
英語的問題Tidyverse 倡導者強調最多的觀點是 Tidyverse 的語法「像英語」,所以更容易教學。
下面對比「英語」的 dplyr 和「非英語」的 data.table(來自這裡[13])。我們要再次使用 R 內置的 mtcars 數據集。
library(data.table)mtdt <- as.data.table(mtcars); mtdt[cyl == 6] # data.table 語法library(dplyr)mttb <- as_tibble(mtcars); filter(mttb, cyl == 6) # dplyr 語法真有什麼區別嗎?初學者即使沒有編程背景,看過一些例子後,也無法快速採用這兩者中的任一種嗎?聲稱 dplyr 具有高度可教學性的老師也會欣然同意他們的學生可以容易地學會 data.table,只要給一些例子,也就是我為初學者所選擇的 base-R。
早些時候我們見過的 purrr 例子
mtcars %>% split(.$cyl) %>% map(~ lm(mpg ~ wt, data = .)) %>% map(summary) %>% map_dbl("r.squared")甚至有經驗(但非 R)的程式設計師也難以理解,這和聲稱的「像英語一樣曉暢」明顯是矛盾的。而且 dplyr 中 mutate 的意思和英語中的意思一點都不接近,也不太可能猜出來,非 R 的專業程式設計師也不行。
換句話說,儘管學生可能會說他們喜歡 Tidy 「英語」的方面,其好處卻不是實在的。如果學習 base-R 而不是 Tidy,他們可能會更精通 R,學得 更快。
順便說一下,如下所述,Tidy 倡導者不喜歡的很多 base-R 函數,名字 確實 使用了英語,例如 plot()、lines()、aggregate() 和 merge()。那麼顯然英語不是核心問題。
管道Tidyverse 還大量使用 magrittr 管道,比如把複合函數 h(g(f(x))) 寫成
這個例子的賣點是「英語」,可以從左向右閱讀。然而,這到底有多少價值?在任何情況下,我個人也都可以從左向右寫這段代碼,無需 使用管道:
作為一名老師,我長期講授程式語言(C、C++、Java、Pascal、Python、R、彙編語言等等),我發現對管道的介紹一直是個麻煩。使用管道的代碼版本隱藏了 g() 和 h() 也各需要一個變量的事實,變量在管道的表達式中並不可見。
假如 w() 需要兩個變量,若第一個變量在管道中使用了,就會隱藏起來,看起來好像就只有一個變量:
> w <- function(u,v) u+2*v> 3 %>% w(5)[1] 13這裡 w() 有兩個變量,但看起來只有一個。
如果我們想讓 3 作為 v,而不是 u 呢?可以做到,用 magrittr 的「點」記法:
這是說明我觀點的又一個例子,Tidy 用額外且不必要的複雜性給學習 R 的人增加了負擔。正如同有 263 個函數的 dplyr,對初學者來說,管道也同樣過於複雜。管道在使用中變體太多了,Hadley 的書 R for Data Science 用了一整章講管道,共 3415 個單詞。
如前所述,初學者一開始只需要學習其中的一小部分內容,但上面的點記法的例子當然還不能算高級案例。初學者每次遇到新的狀況,都必須從無數變體中篩選, dplyr、purrr、管道或者別的什麼。
此外,如果上述函數 h() 需要兩個變量而不是一個,並且每一個變量都需要函數的複合呢?管道就沒法用了。
更為重要的是,即使管道的倡導者也會承認管道調試更加困難;作為對比,我上面寫的那種風格很容易調試。另外,問題規模大的時候,用管道的代碼運行較慢。
Tidy 倡導者提出管道的好處是「從左向右」執行。他們承認無需管道也能做到這點,但是強調需要付出創建變量存儲中間結果的代價。這是個有效的觀點,但是得到的好處不大。和給學習 R 的人帶來的認知過載、調試困難等問題比,值得嗎?在我看來顯然不值得。
代碼可讀性Tidyverse 倡導者還提出 dplyr 的「英語」用法讓代碼更容易「閱讀」,而不僅是編寫。在我看來,這錯過了重點;任何軟體工程的老師都會告訴你,最佳代碼可讀性來自使用 真正 英語編寫良好、有意義的代碼注釋。寫注釋對非程式設計師來說同樣重要,甚至可能更重要。
我的 R 風格導引[14] 中提到了更多可讀性問題。
總結:Tidyverse 在教學中的合理地位正如我前面所說,與成功使用 Tidyverse 指導初學者程式設計師的老師討論時,我問他們學生是否沒有能力只學習 base-R,他們承認答案是否定的。事實上,在 Tidyverse 之前,大量在過去沒有任何編程背景的人都在學習 base-R,。
如前所述,Tidyverse 難以調試,並且在大型數據集上運行緩慢。所感知的「像英語」的益處是虛幻的。
簡言之,在我看來,通過 Tidyverse 講授 R 沒有任何好處,而且存在一些重大的缺點。我認為在向初學者講授 R 時採用 Tidyverse 是錯誤的,原因如下:
1.複雜,Tidyverse 中新函數新概念太多。
2.難以調試。
3.泛化能力差。
推薦教學:
R 的課程,特別是面向非程式設計師的課程,應當以 base-R 建立穩固的基礎作為第一要務。
Tidy 在 R 課程中的適當位置應該是:
•dplyr:與 data.table 一起在中等 R 級別教學。
•purrr:僅在高等級別教學.
•管道:在中等級別教學,作為一個對有些學生在有些情況下有用的 選項,(而非作為 必須 採用的工作方式)。
我當然不是說應該只使用 base-R;正相反,CRAN 是 R 的一大優勢,我也大量使用,R 初學者絕對應該知道這個。
但是,Tidyverse 應被視為高級的 R,不是面向初學者的入門級別的 R,就像大多數複雜的 CRAN 包一樣,Tidyverse 應該作為 選項 被呈現,而非 必須 的方式。
RStudio 的作用
在我看來,RStudio 可以很容易地解決這個問題。可以採取以下措施,大大改善「壟斷」問題:
1.向初學者推廣 base-R 的教學,把 Tidyverse 作為高級課題。R for Everyone: Advanced Analytics and Graphics (second ed.),作者 Jared Lander 這本流行書就是這樣做的!
2.在 RStudio 各種關於編寫快速 R 代碼的網頁中,給予 data.table 同等對待。
References[1] 同意: https://github.com/matloff/TidyverseSkeptic/issues/22
[2] 賜教: https://github.com/boltomli/TidyverseSkeptic/issues/new
[3] 英文原文全文: https://github.com/matloff/TidyverseSkeptic/blob/master/READMEFull.md
[4] 公開: https://matloff.wordpress.com/2018/02/22/xie-yihui-r-superstar-and-mensch/
[5] 這裡是我的簡歷。: http://heather.cs.ucdavis.edu/matloff.html
[6] fasteR: http://github.com/matloff/fasteR
[7] 「遵循 Tidyverse」: https://twitter.com/GSwithR/status/996830294367002625
[8] 「Tidyverse 詛咒」: https://www.r-bloggers.com/the-tidyverse-curse
[9] 指出: https://twitter.com/MattDowle/status/1142001162230489088
[10] Charavarty 和 Keller: https://www-ps.informatik.uni-kiel.de/~mh/reports/fdpe02/papers/paper15.ps.gz
[11] 在線教程: https://towardsdatascience.com/functional-programming-in-r-with-purrr-469e597d0229
[12] 推特討論: https://twitter.com/dgkeyes/status/1200532987000971264
[13] 這裡: https://atrebas.github.io/post/2019-03-03-datatable-dplyr/
[14] R 風格導引: http://github.com/matloff/R-Style-Guide統計之都:專業、人本、正直的中國統計學社區。
關注方式:掃描下圖二維碼。或查找公眾號,搜索 統計之都 或 CapStat 即可。
往期推送:進入統計之都會話窗口,點擊右上角小人圖標,查看歷史消息即可。
點擊「閱讀原文」,閱讀更多!