一小時向非程序員介紹 R 編程語言
我妹妹正在念大四,主修社會學。她剛剛簽了下個學期一份不錯的分析員工作,對方告訴她工作中要用到 R 編程語言。她讓我在寒假時教教她,我欣然同意了。還有什么比這更好的方式來消磨明尼蘇達的冬天呢?[注1]
問題是:在原定教她的那天,我們倆都有空的時間只有一個小時。哎呀!
不過我還是接受了這個挑戰,用一個小時向我的社會學家妹妹介紹R。下面就是我所做的事情。我沒有預先做功課,而且肯定犯了些錯誤,忽視了核心思想,糾纏于細枝末節。但妹妹給我的反饋是非常好(我確實對其他人的“一小時學會R”理念非常感興趣)
(1)下載R和RStudio
我對RStudio的印象不錯,對于初學者來說,它既方便又很有幫助,對專業人士也很有用。尤其對于初學者:鼠標指向-點擊式(point-and-click)的選項非常棒,工作區面板對于建立起對R環境的概念也非常有用。我甚至都不用再花精力向我妹妹介紹R默認的集成開發環境——我馬上就讓她下載了RStudio,不過你仍然需要下載普通版的R。下載之后,我意識到r-project.org網站真應該在設計上進行大修整,因為:(a)它不夠漂亮(b)如果你不知道什么是“CRAN鏡像”,下載R將是一件容易把人搞糊涂的事。
(2)控制臺和腳本
準備好之后,我們做的第一件事就是在控制臺中鍵入如下兩行代碼:
> x = 7 > x + 9 [1] 16
這并非純粹的“Hello World”,但它闡明了一些概念,比如”賦值”、”變量”和”求值”[注2]。
接著,我讓妹妹在一個R腳本文件中保存了上面那兩行代碼(我認為,在初學者開始使用一門語言時就教會他們如何正確地把代碼保存在腳本文件中是非常重要的)。然后,我教她怎么用Cmd-Enter組合鍵(譯者注:這是Mac OS的鍵位。在PC中,對應的組合鍵是Ctrl+Enter)在控制臺中執行代碼。
在解釋這些內容的過程中,我意識到”控制臺”和”腳本”這類術語比較晦澀,所以我盡可能給出它們的明確的定義。我也不得不小心地使用那些含義確切的詞而非”REPL”或”prompt”這類詞匯
(3)注釋
# 注釋特別重要,所以我們學習了它
(4)圖形
腳本、注釋和控制臺可能有點兒枯燥,所以到了這一步,該是從圖形中尋找點兒樂趣的時候了!這是我們繪制的一張圖:
x = rnorm(1000, mean = 100, sd = 3) hist(x)
教我妹妹理解這段代碼涉及解釋什么是函數(因為rnorm和hist都是函數)、什么是函數的實參,以及為什么你可以通過名字引用實參卻不一定非得這樣做。
我還教她怎么保存一個圖形——借助圖形窗口中方便的“Export”按鈕,在RStudio中保存圖形非常容易。
(5)獲得幫助
我認為,“獲取幫助”是這類快速入門過程中需要掌握的最重要的概念。顯然你不可能在一個小時之內學會一切,所以,你真正需要的是當你用到時可以查找到相應信息的工具。下面是我介紹的語法:
# 如果你知道函數名,但不知道怎么使用 ?chisq.test # 如果你知道要做什么,但不知道函數名 ??chisquare
考慮到查函數文檔對非程序員來說不太容易,這本來或許不是一個正確的策略。我考慮過強調google技巧的重要性(我在研究生院學到的最有用的東西),或者介紹StackOverFlow和R-help,但最后還是決定講解官方的文檔系統。”在R中我該怎么做X這件事”是初學者最常見的問題之一,我認為這個問題的答案可能應該是”使用函數Y( )”——所以重要的是能夠搞清楚如何使用函數Y( )。
在我看來,初學者最常見的另一個問題是”我遇到了出錯信息Z,怎么修正它?”。為解決這個問題,我演示一些常見的錯誤(對象未找到,意外的<X>常量,等等)并解釋了它們的含義。
(6)數據類型
查看幫助文檔讓我想起文檔中經常會提及某個函數的實參必須是某個特定的類型,因此我們或許應該討論一下數據類型。我介紹了:
向量
# 字符串向量 > y = c("apple", "apple", "banana", "kiwi", "bear", "strawberry", "strawberry") > length(y) [1] 7 # 數值向量 > numbers = rep(3, 99) > numbers [1] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 [39] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 [77] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
矩陣
> mymatrix = matrix(c(10, 15, 3, 29), nrow = 2, byrow = TRUE) > mymatrix [,1] [,2] [1,] 10 15 [2,] 3 29 > t(mymatrix) [,1] [,2] [1,] 10 3 [2,] 15 29 > solve(mymatrix) [,1] [,2] [1,] 0.1183673 -0.06122449 [2,] -0.0122449 0.04081633 > mymatrix %*% solve(mymatrix) [,1] [,2] [1,] 1 0 [2,] 0 1 > chisq.test(mymatrix) Pearson's Chi-squared test with Yates' continuity correction data: mymatrix X-squared = 5.8385, df = 1, p-value = 0.01568
數據框(dataframe)
# 設置工作目錄 setwd("~/Documents/R_intro") # 讀入一個數據集 wages = read.table("wages.csv", sep = ",", header = TRUE)
就這樣,我們借助實例討論了一些數據類型,并順帶著學習了其他一些重要的內容,像怎么確定向量中元素的個數、什么是工作目錄,以及怎樣讀入數據文件。
(7)探索性數據分析
一旦你讀入了一個數據集,事情就開始變得有趣了。我們從中學習了一大堆東西,像怎么做基本的表格、遇到缺失數據如何處理,以及怎么擬合一個簡單的線性模型。這部分的內容相當有趣,以至于我妹妹開始主導學習過程了:不再是我說“我要教你如何做什么”,而是她主動問“嗯,我們能畫一個散點圖嗎?”或“你覺得我們可以把最優擬合直線放到那個圖上嗎?”我真為此而感到高興——我希望這意味著她已全身心投入并樂在其中。
> names(wages) [1] "edlevel" "south" "sex" "workyr" "union" "wage" "age" [8] "race" "marital" > class(wages$marital) [1] "integer" > table(wages$union) not union member union member 438 96 > summary(wages$workyr) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.00 8.00 15.00 17.82 26.00 55.00 > nrow(wages) [1] 534 > length(which(is.na(wages$sex))) [1] 0 > linmod = lm(workyr ~ age, data = wages) > summary(linmod)
我們還進一步學習了圖形,像怎么作出好的直方圖,以及怎么在回歸直線上疊加散點圖。
hist(wages$wage, xlab = "hourly wage", main = "wages in our dataset", col = "purple") plot(wages$age, wages$workyr, xlab = "age", ylab="years worked", main = "age vs. years worked") abline(lm(wages$workyr ~ wages$age), col="red", lwd = 2)
好了,時間到。
我遺漏了些什么?哪些事能做得更好?我事后想到的有:
- 用[]取子集. 這是個關鍵知識點。它可以應用于我所介紹的所有數據類型,而且極為有用。我真希望當時有時間讓我妹妹做一個,比如只包含女性的工資直方圖
- 編程相關的東西:循環、if語句、用戶自定義函數,等等。不過我覺得不教這些東西也沒問題——考慮到受眾,我是把R當作一個數據分析環境而非一種編程語言來教授。
- 保存.rda文件和/或工作區
- 安裝和載入包
- 其他數據類(比如列表)
- 其他(更好的?)幫助資源/提示/技巧
最后一點感想
總的來說,在一小時內介紹R讓我收獲了樂趣,而且我認為(希望?)我妹妹也是如此。臨別時我又給了她一些資料:這個,這個和這個,這些資料我都不是非常熟悉——但我知道,要想能夠用R分析實際數據,所需的時間遠大于在我這兒的一個小時。我相信我已經覆蓋了大部分基礎知識,我妹妹也覺得這對她非常有幫助。我很樂意聽各位來談談你是如何應對”一小時內向非程序員介紹R”這個挑戰的。
腳注
注1. 即便對明尼蘇達來說,天氣也真的太冷了。溫度已在華氏0度(譯者注:攝氏-17度)左右徘徊了一個月之久。星期一的最高溫度是華氏-12度(譯者注:攝氏-24度)
注2.你可能注意到了,我用“=”來賦值,而且把這個習慣傳給了我妹妹。我考慮過這個問題并堅持這一用法,“<-”要多敲鍵盤,我發現它唯一有用的地方只是當我在system.time函數調用內進行賦值。
原文鏈接: alyssa frazee 翻譯: 伯樂在線 - LieGroup
譯文鏈接: http://blog.jobbole.com/55093/