1. 程式人生 > >R語言(入門小練習篇)

R語言(入門小練習篇)

問題:

  一組學生參加了數學、科學和英語考試。為了給所有的學生確定一個單一的成績衡量指標,需要將這些科目的成績組合起來。另外,還想將前20%的學生評定為A,接下來20%的學生評定為B,以此類推。最後,希望按字母順序對學生排序。

Excel中的資料表(自己一個個敲的,最討厭做的事情TT)

StuId StuName Math Science English
1 John Davis 502 95 25
2 Angela Williams 465 67 12
3 Bull Jones 621 78 22
4 Cheryl Cushing 575 66 18
5 Reuven Ytzrhak 454 96 15
6 Joel Knox 634 89 30
7 Mary Rayburn 576 78 37
8 Greg England 421 56 12
9 Brad Tmac 599 68 22
10 Tracy Mcgrady 666 100 38

step1:輸入資料——R語言匯入xlsx

1 #1資料輸入
2 install.packages("xlsx")
3 library(xlsx)
4 workbook<-"D:/R語言/code/R語言實戰前五章小試身手/StuScore.xlsx
"#也可用‘\\’注意轉義字元 5 StuScore<-read.xlsx(workbook,1)#1表示sheet1 6 StuScore

step2:資料預處理——將變數進行標準化

因為數學,科學和英語考試的分值不同(均值和標準差均有較大差異),在組合之前要讓他們變得可以比較

方法:變數標準化,把每科成績都用單位標準差表示

  tips:

所謂資料的標準化是指中心化之後的資料在除以資料集的標準差,即資料集中的各項資料減去資料集的均值再除以資料集的標準差。
例如有資料集1, 2, 3, 6, 3,其均值為3,其標準差為1.87,那麼標準化之後的資料集為(1-3)/1.87,(2
-3)/1.87,(3-3)/1.87,(6-3)/1.87,(3-3)/1.87,即:-1.069,-0.535,0,1.604,0 資料中心化和標準化的意義是一樣的,為了消除量綱對資料結構的影響。

  這裡使用scale()可以直接實現

複製程式碼
 1 > #2資料預處理
 2 > options(digits=2)#限定為2位小數
 3 > afterscale<-scale(StuScore[,3:5])
 4 > afterscale
 5        Math Science English
 6  [1,] -0.58   1.040    0.20
 7  [2,] -1.02  -0.815   -1.17
 8  [3,]  0.82  -0.086   -0.12
 9  [4,]  0.28  -0.881   -0.54
10  [5,] -1.15   1.106   -0.86
11  [6,]  0.98   0.643    0.73
12  [7,]  0.29  -0.086    1.47
13  [8,] -1.54  -1.544   -1.17
14  [9,]  0.56  -0.749   -0.12
15 [10,]  1.35   1.372    1.57
16 attr(,"scaled:center")
17    Math Science English 
18     551      79      23 
19 attr(,"scaled:scale")
20    Math Science English 
21    84.7    15.1     9.5 
複製程式碼

  這裡,有兩個疑問:

  1.說好的輸出兩位小數呢?Science那一欄輸出的都是三位小數,怎麼回事?

  2.這是什麼東東?

  1. 1 attr(,"scaled:center")
    2    Math Science English 
    3     551      79      23 
    4 attr(,"scaled:scale")
    5    Math Science English 
    6    84.7    15.1     9.5

    scale方法中的兩個引數center和scale的解釋:
          1.center和scale預設為真,即T或者TRUE
          2.center為真表示資料中心化
          3.scale為真表示資料標準化

   也就是說:center表示一列資料的均值,scale則表示標準差(有興趣的同學,可以用Excel的STDEV函式驗證一下)

step3:通過函式mean()來計算各行的均值以及獲得綜合得分,並使用cbind()將其新增到花名冊中

複製程式碼
 1 > #3在afterscale中計算標準差均值,並將其新增到StuScore
 2 > score<-apply(afterscale,1,mean)#1表示行,mean表示均值函式
 3 > StuScore<-cbind(StuScore,score)
 4 > StuScore
 5    StuId         StuName Math Science English score
 6 1      1      John Davis  502      95      25  0.22
 7 2      2 Angela Williams  465      67      12 -1.00
 8 3      3      Bull Jones  621      78      22  0.21
 9 4      4  Cheryl Cushing  575      66      18 -0.38
10 5      5  Reuven Ytzrhak  454      96      15 -0.30
11 6      6       Joel Knox  634      89      30  0.78
12 7      7    Mary Rayburn  576      78      37  0.56
13 8      8    Greg England  421      56      12 -1.42
14 9      9       Brad Tmac  599      68      22 -0.10
15 10    10   Tracy Mcgrady  666     100      38  1.43
複製程式碼

Step4:函式quantile()給出學生綜合得分的百分位數

  quantile(x,probs):求分位數,其中x為待求分位數的數值型向量,probs為一個由[0,1]之間的概率值組成的數值向量

1 > afterquantile<-quantile(score,c(.8,.6,.4,.2))
2 > afterquantile
3   80%   60%   40%   20% 
4  0.60  0.21 -0.18 -0.50 

step5:使用邏輯運算子,把score轉為等級(離散型)

複製程式碼
 1 > #5使用邏輯運算子,把score轉為等級(離散型)
 2 > StuScore$grade[score>=afterquantile[1]]<-"A"
 3 > StuScore$grade[score<afterquantile[1]&&score>=afterquantile[2]]<-"B"
 4 > StuScore$grade[score<afterquantile[2]&&score>=afterquantile[3]]<-"C"
 5 > StuScore$grade[score<afterquantile[3]&&score>=afterquantile[4]]<-"D"
 6 > StuScore$grade[score<afterquantile[4]]<-"E"
 7 > StuScore
 8    StuId         StuName Math Science English score grade
 9 1      1      John Davis  502      95      25  0.22     B
10 2      2 Angela Williams  465      67      12 -1.00     E
11 3      3      Bull Jones  621      78      22  0.21     B
12 4      4  Cheryl Cushing  575      66      18 -0.38     E
13 5      5  Reuven Ytzrhak  454      96      15 -0.30     E
14 6      6       Joel Knox  634      89      30  0.78     B
15 7      7    Mary Rayburn  576      78      37  0.56     B
16 8      8    Greg England  421      56      12 -1.42     E
17 9      9       Brad Tmac  599      68      22 -0.10     E
18 10    10   Tracy Mcgrady  666     100      38  1.43     B
複製程式碼

Step6:使用strsplit()以空格為界把學生姓名拆分為姓氏和名字

1 > #Step6:使用strsplit()以空格為界把學生姓名拆分為姓氏和名字
2 > name<-strsplit((StuScore$StuName)," ")
3 Error in strsplit((StuScore$StuName), " ") : non-character argument
4 > name
5 [1] "Jim"  "Tony" "Lisa" "Tom" 

  這裡出錯了,原因很明確,沒有字元型的引數傳入,反應過來,原來是用execl匯入的時候,StuName那一列預設的是什麼型別的呢?我們來檢測一下

複製程式碼
 1 > is.numeric(StuScore$StuName)
 2 [1] FALSE
 3 > is.logical(StuScore$StuName)
 4 [1] FALSE
 5 > is.character(StuScore$StuName)
 6 [1] FALSE
 7 > is.complex(StuScore$StuName)
 8 [1] FALSE
 9 > help(type)
10 > typeof(StuScore$StuName)
11 [1] "integer"
複製程式碼

  因此,我們把他改為字元型

複製程式碼
 1 > #Step6:使用strsplit()以空格為界把學生姓名拆分為姓氏和名字
 2 > StuScore$StuName<-as.character(StuScore$StuName)
 3 > is.character(StuScore$StuName)
 4 [1] TRUE
 5 > name<-strsplit(StuScore$StuName," ")
 6 > name
 7 [[1]]
 8 [1] "John"  "Davis"
 9 
10 [[2]]
11 [1] "Angela"   "Williams"
12 
13 [[3]]
14 [1] "Bull"  "Jones"
15 
16 [[4]]
17 [1] "Cheryl"  "Cushing"
18 
19 [[5]]
20 [1] "Reuven"  "Ytzrhak"
21 
22 [[6]]
23 [1] "Joel" "Knox"
24 
25 [[7]]
26 [1] "Mary"    "Rayburn"
27 
28 [[8]]
29 [1] "Greg"    "England"
30 
31 [[9]]
32 [1] "Brad" "Tmac"
33 
34 [[10]]
35 [1] "Tracy"   "Mcgrady"
複製程式碼

Step7:把name分成Firstname和LastName,加入到StuScore中

複製程式碼
 1 > #7把name分成Firstname和LastName,加入到StuScore中
 2 > FirstName<-sapply(name,"[",1)
 3 > LastName<-sapply(name,"[",2)
 4 > StuScore<-cbind(FirstName,LastName,StuScore[,-1])
 5 > StuScore
 6    FirstName LastName LastName         StuName Math Science English score grade
 7 1       John    Davis    Davis      John Davis  502      95      25  0.22     B
 8 2     Angela Williams Williams Angela Williams  465      67      12 -1.00     E
 9 3       Bull    Jones    Jones      Bull Jones  621      78      22  0.21     B
10 4     Cheryl  Cushing  Cushing  Cheryl Cushing  575      66      18 -0.38     E
11 5     Reuven  Ytzrhak  Ytzrhak  Reuven Ytzrhak  454      96      15 -0.30     E
12