從另一個視角看 R 語言的方言 Tidyverse

2021-02-19 統計之都

從另一個視角看 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() 區別何在?在何種情況下應該使用哪個函數?用戶必須加以篩選。

關於 dplyrdata.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 個單詞。

如前所述,初學者一開始只需要學習其中的一小部分內容,但上面的點記法的例子當然還不能算高級案例。初學者每次遇到新的狀況,都必須從無數變體中篩選, dplyrpurrr、管道或者別的什麼。

此外,如果上述函數 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 即可。

往期推送:進入統計之都會話窗口,點擊右上角小人圖標,查看歷史消息即可。

點擊「閱讀原文」,閱讀更多!

相關焦點

  • R語言學習指南(3) tidyverse的基礎使用
    tidyverse是為數據科學設計的R軟體包,它包含(ggplot2、dplyr、tidyr、stringr、magrittr、tibble)等一系列熱門軟體包,學好tidyverse的使用可也讓你站上另一個高度,從而高效的處理數據,因此本文檔不僅僅做一些案例介紹,而是希望以較為正確的學習方法來介紹R語言,使大家少走彎路,快速入門掌握R語言
  • 【數據管理】Tidyverse:R 語言學習之旅的新起點
    2 您用tidyverse包嗎?學習R語言的傳統路徑(base R first)多是從變量類型、數據結構、流程控制、循環與自定義函數,也就是以R程式設計作為起點,接著依照數據處理、視覺化、統計與機器學習等應用偏好延續下一個學習的旅程;由tidyverse
  • R語言 | Tidyverse包入門介紹
    今天,我們講一個「讓R能夠和Python在數據處理方面一較高下」的擴展包:tidyverse包。以此為契機,統計學家Hadley Wickham開發出了一系列數據處理的包,整合成為一個,這就是tidyverse包,它裡面包括了與數據處理相關的內容,如ggplot2,dplyr,tidyr,tibble等等。你可以直接調用tidyverse,也可以調用它所轄屬的包。下面,我們講解一些tidyverse中可能使用到的函數,幫助你快速上手這個方便的東西。
  • 【tidyverse】R中的tidyverse入門
    tidyverse是由RStudio首席科學家Hadley Wickham開發的R套裝的集合。以下教程將介紹tidyverse中用於構建和分析數據集的一些基本功能。 這是關於清理數據的三部分系列中的第一部分,使用tidyverse在R中對其進行可視化。加載包首先,安裝tidyverse,然後加載tidyverse和magrittr。
  • R入門?從Tidyverse學起!
    那麼,tidyverse就提供了一個很好的學習思路(tidyverse first),讓我們先忽略編程這道大關,其理念是一開始不談向量、矩陣、數據框、因子、流程控制等概念,直接從數據的操縱入手,讓初學者在最短時間內學會數據的處理與可視化應用。
  • R語言入門教程 | tidyverse包之數據處理
    (中文第二版是2016年),主要著力點也是在R base上,R語言可視化的ggplot2包也只是簡要介紹,而對於tidyverse包,《R語言實戰》並未涉及,這也導致R語言的學習難度增加,今天我們給大家引入tidyverse包的學習。
  • Tidy時代R語言學習的一些ABC
    新年的第一個計劃,寫一個關於R語言數據處理和操作的教程,突出tidyverse出現之後的新方法。下面這篇小文章,給出了一個tidy時代R語言的入門書單和一些網絡資源。不全面,更不權威,就作為這個新教程系列的參考資料吧。
  • R語言必知必會之tidyverse(一):管道操作
    徵得張敬信老師同意,本號將轉載張老師關於R語言tidyverse包一系列文章,為大家進行醫學研究提供助力。
  • tidyverse —— readr包
    tidyverse默認用utf-8進行編碼。對於要進行解析的字符串,要先弄清楚原碼。l1 <- read.csv('F:/action/tidyverse/data/CSR_Finidx.csv', sep = ",", fileEncoding = "UTF-16")view(l1)
  • tidyverse —— readxl包
    readxl包,讀取Excel文件專用包,有和tidyverse核心包一樣的特點,快!效率特高!話說Hadley大叔出品就沒有效率低的,可能鍵盤是借來的,著急還。獨立性高,不外部依賴Java啥的,xls和xlsx文件讀取都可以。
  • 數據清理工具簡介(Tidyverse)
    為了加快數據清理的效率,同時為以後的建模和數據可視化做準備,R語言的Tidyverse包可以提供非常優秀的數據清理、整合和可視化的「一站式服務」。安裝Tidy首先安裝Tidyverse, 代碼如下所示。其實Tidyverse是一系列優秀軟體庫的合集,其中最常用的幾個package包括 dplyr,ggplot2 和 readr 等。 if (!
  • [R數據科學]tidyverse數據清洗案例詳解
    如果你想了解更多的基本理論,你可能會喜歡發表在《統計軟體雜誌》上的tidy data論文[1]。本文框架數據清洗案例我們主要通過一個案例,來了解如何整潔數據,並將案例中的各個有用函數進行詳細解讀。library(tidyverse) #加載包who #數據展示
  • R語言 | 數據操作dplyr包
    [更新~] Python網絡爬蟲與文本數據分析公眾號只帶著Python字眼,卻分享著R語言,不務正業,任性了~dplyr簡介dplyr是R語言的數據分析包,很像python中的pandas,能對dataframe
  • tidyverse —— forcats包
    作者簡介野菜糰子,R語言中文社區專欄作者
  • R數據科學--初見
    給自己一個全新的R語言環境」 --圖文版教程"生信技能樹 史上最貼心R包安裝示範視頻"--視頻版教程認識Rstudio的界面 3.tidyverse--一個R包合集R包是函數、數據和文檔(documentation)的集合,是對R基礎功能的擴展。R包只需安裝一次,但每次打開新的session都要重新加載。
  • 地理數據科學培訓班第一課之初識R語言
    在文章的最後我還通過一個案例帶大家走進奇幻的 R 世界。安裝 R下載頁面:https://mirrors.tuna.tsinghua.edu.cn/CRAN/我安裝的 R 語言是 R version 4.0.2 (2020-06-22),該發行版的名字是 Arbor Day。
  • R語言如何檢測和處理數據缺失值?
    【代碼片段】# R包library(pacman)p_load(tidyverse) # 數據科學套件p_load(mice) # 缺失值分析包p_load(VIM)# 導入數據telecom_data <- read_csv('.
  • R語言小白入門課| 一刻鐘教你學會正則表達式
    在前兩期的內容中(十分鐘輕鬆學會R數據清洗技巧,生信小白必須跨越的第一關;R語言小白入門課|一刻鐘帶你學會R數據轉化),我們基於tidyverse包的核心包dplyr包,分別介紹了filter(),arrange(),select(),mutate(),以及summarize()5大函數的功能與使用方法
  • R語言學習資源匯總(分學科)
    SPSS,STATA等等有一定的差別,在犧牲界面操作(滑鼠點點點)的同時結合了一些計算機程式語言的特點,更像是一門專為統計學家量身定製的程式語言,且由於歷史悠久、開源等特點,不少學術界人士會選擇自行開發一個R包作為其學術產出。
  • R語言數據處理全流程教學
    R 語言作為一款功能強大的統計分析、繪圖和數據挖掘軟體,被社會科學領域的研究者們廣泛應用於數據處理和圖表製作等工作。由於 R 語言需要一定的編程基礎,其開源屬性又帶來了千千萬萬的功能包(package),使得 R 語言的初學者常常不知從何入手,不知道學習哪些代碼與功能包足夠滿足自己的統計需求。