1. 程式人生 > >R in Action學習筆記:一個簡單的資料處理例項

R in Action學習筆記:一個簡單的資料處理例項

這是來自《R in Action》中的一個數據處理例項。
資料:一組學生的名字和其對應的數學、科學、英語的成績;

資料分析需求:

1、為所有學生確定一個單一的成績衡量指標;
2、將前20%的學生評定為A,接下來20%的學生評定為B,依次類推;
3、按照學生姓氏的字母順序對學生排序。

要考慮的問題:

1、由於各科成績的均值和標準差相去甚遠,所以這些成績無法直接組合,對它們求平均值是沒有意義的。在組合這些考試成績之前,必須將其變換為可比較的單元;
2、為了評定等級,需要一種方法來確定某個學生在前述得分上百分比排名;
3、表示姓名的欄位只有一個,這讓排序任務複雜化了。為了正確地將其排序,需要將姓和名拆開。

學生成績資料:

學生姓名 數學 科學 英語
John Davis 502 95 25
Angela Williams 600 99 22
Bullwinkle Moose 412 80 18
David Jones 358 82 15
Janice Markhammer 495 75 20
Cheryl Cushing 512 85 28
Reuven Ytzrhak 410 80 15
Greg Knox 625 95 30
Joel England 573 89 27
Mary Rayburn 522 86 18

用到的資料處理函式:

scale()函式
scale(x,center=TRUE, scale=TRUE)
為資料物件x按列進行中心化(center=TRUE)或標準化(center=TRUE,scale =TRUE);
預設情況下,函式scale()對矩陣或資料框的指定列進行均值為0、標準差為1

的標準化: newdata <- scale(mydata)
要對每一列進行任意均值和標準差的標準化:newdata <- scale(mydata) * SD + M,其中M是想要的均值,SD為想要的標準差。

apply()函式
沿著陣列的某一維度處理資料,apply(陣列,維度,函式/函式名),第一個引數是指要參與計算的矩陣;第二個引數是指按照哪個維度進行計算,第三個引數是指具體的運算引數。

sapply()函式
可以迴圈處理列表中的每一個元素,sapply(列表,函式/函式名,其他引數),總是返回一個列表。

strsplit()函式
strsplit(x, split, fixed=FALSE) 在split處分割字元向量x中的元素。若fixed=FALSE,則 pattern為一個正則表示式。若fixed=TRUE,則pattern為一個文字字串。例如,y <- strsplit(“abc”, “”)將返回一個含有1個成分、3個元素的列表,包含的內容為"a" “b” “c” 。

主要程式碼如下:
options(digits = 2)  # 限定了輸出小數點後數字的位數,並且讓輸出更容易閱讀。 
# 將學生資訊與成績資訊儲存為向量
student <- c("John Davis","Angela Williams","Bullwinkle Moose","David Jones",
             "Janice Markhammer","Cheryl Cushing","Reuven Ytzrhak","Greg Knox",
             "Joel England","Mary Rayburn")
math <- c(502,600,412,358,495,512,410,625,573,522)
science <- c(95,99,80,82,75,85,80,95,89,86)
english <- c(25,22,18,15,20,28,15,30,27,18)
# 建立資料框,使用引數stringsAsFactors = FALSE關閉R自動將字串轉換為因子Factor的功能。
roster <- data.frame(student,math,science,english,stringsAsFactors = FALSE)

roster # 輸出結果
student math science english
1 John Davis 502 95 25
2 Angela Williams 600 99 22
3 Bullwinkle Moose 412 80 18
4 David Jones 358 82 15
5 Janice Markhammer 495 75 20
6 Cheryl Cushing 512 85 28
7 Reuven Ytzrhak 410 80 15
8 Greg Knox 625 95 30
9 Joel England 573 89 27
10 Mary Rayburn 522 86 18

# 計算綜合得分,將各科成績變數進行標準化,這樣每科成績都使用單位標準差來表示
z <- scale(roster[,2:4])

# 使用mean函式計算各行的均值,並使用cbind函式將其新增到花名冊roster中
score <- apply(z,1,mean)
roster <- cbind(roster,score)

# 使用函式quantile計算學生綜合得分的百分位數
y <- quantile(score,c(.8,.6,.4,.2))

# 使用邏輯運算子,將學生的百分位數排名重編碼為一個新的類別型成績變數
roster$grade[score >= y[1]] <- "A"
roster$grade[score < y[1] & score >= y[2]] <- "B"
roster$grade[score < y[2] & score >= y[3]] <- "C"
roster$grade[score < y[3] & score >= y[4]] <- "D"
roster$grade[score < y[4]] <- "F"

roster # 處理後的roster
student math science english score grade
1 John Davis 502 95 25 0.56 B
2 Angela Williams 600 99 22 0.92 A
3 Bullwinkle Moose 412 80 18 -0.86 D
4 David Jones 358 82 15 -1.16 F
5 Janice Markhammer 495 75 20 -0.63 D
6 Cheryl Cushing 512 85 28 0.35 C
7 Reuven Ytzrhak 410 80 15 -1.05 F
8 Greg Knox 625 95 30 1.34 A
9 Joel England 573 89 27 0.70 B
10 Mary Rayburn 522 86 18 -0.18 C

# 抽取姓氏和名字,strsplit函式應用到一個字串組成的向量上會返回一個列表
name <- strsplit((roster$student)," ")
#  "["是一個可以提取某個物件的一部分的函式——在這裡它是用來提取列表name各成分中的第一個或第二個元素
# 由於已經不再需要student變數,故將其丟棄(在下標中使用-1代表將第1列去掉) 
lastname <- sapply(name,"[",2)
firstname <- sapply(name,"[",1)
roster <- cbind(firstname,lastname,roster[,-1])
# 使用函式order()依姓氏和名字對資料集進行排序
roster <- roster[order(lastname,firstname),]

roster # 排序後的roster
firstname lastname math science english score grade
6 Cheryl Cushing 512 85 28 0.35 C
1 John Davis 502 95 25 0.56 B
9 Joel England 573 89 27 0.70 B
4 David Jones 358 82 15 -1.16 F
8 Greg Knox 625 95 30 1.34 A
5 Janice Markhammer 495 75 20 -0.63 D
3 Bullwinkle Moose 412 80 18 -0.86 D
10 Mary Rayburn 522 86 18 -0.18 C
2 Angela Williams 600 99 22 0.92 A
7 Reuven Ytzrhak 410 80 15 -1.05 F

END