本章內(nèi)容
1.數(shù)學(xué)和統(tǒng)計(jì)函數(shù)
2.字符處理函數(shù)
3.循環(huán)和條件執(zhí)行
4.自編函數(shù)
5.數(shù)據(jù)整合與重塑
第一部分,我們將快速瀏覽R中的多種數(shù)學(xué)、統(tǒng)計(jì)和字符處理函數(shù)。為了讓這一部分的內(nèi)容相互關(guān)聯(lián),我們先引入一個(gè)能夠使用這些函數(shù)解決的數(shù)據(jù)處理問(wèn)題。在講解過(guò)這些函數(shù)以后,再為這個(gè)數(shù)據(jù)處理問(wèn)題提供一個(gè)可能的解決方案。
第二部分,我們將講解如何自己編寫(xiě)函數(shù)來(lái)完成數(shù)據(jù)處理和分析任務(wù)。首先,我們將探索控制程序流程的多種方式,包括循環(huán)和條件執(zhí)行語(yǔ)句。然后,我們將研究用戶自編函數(shù)的結(jié)構(gòu),以及在編寫(xiě)完成后如何調(diào)用它們。
第三部分,我們將了解數(shù)據(jù)的整合和概述方法,以及數(shù)據(jù)集的重塑和重構(gòu)方法。在整合數(shù)據(jù)時(shí),你可以使用任何內(nèi)建或自編函數(shù)來(lái)獲取數(shù)據(jù)的概述,所以你在本章前兩部分中學(xué)習(xí)的內(nèi)容將會(huì)派上用場(chǎng)。
5.1 利用R中的數(shù)值和字符處理函數(shù)處理解決實(shí)際問(wèn)題
5.2 數(shù)值和字符處理函數(shù)
R中數(shù)據(jù)處理函數(shù),它們可分為數(shù)值(數(shù)學(xué)、統(tǒng)計(jì)、概率)函數(shù)和字符處理函數(shù)。
本例將展示如何將函數(shù)應(yīng)用到矩陣和數(shù)據(jù)框的列(變量)和行(觀測(cè))上。
01 數(shù)學(xué)函數(shù)
參考書(shū)籍表5-2,表中列出了常用的數(shù)學(xué)函數(shù)和簡(jiǎn)短的用例。表中共計(jì)13類常用的數(shù)學(xué)函數(shù),主要作用是對(duì)數(shù)據(jù)進(jìn)行變換和運(yùn)算。表中函數(shù)被應(yīng)用于數(shù)值向量、矩陣或數(shù)據(jù)框時(shí),它們會(huì)作用于每一個(gè)獨(dú)立的值。例如,
sqrt(c(4, 16, 25)) 的返回值為 c(2,4, 5)。
02 統(tǒng)計(jì)函數(shù)
常用的統(tǒng)計(jì)函數(shù)參考書(shū)籍表5-3,表中許多函數(shù)參數(shù)都是可選的,參數(shù)不同,結(jié)果亦不同,比如求平均數(shù)、中位數(shù)、標(biāo)準(zhǔn)差、方差等。

#實(shí)戰(zhàn)應(yīng)用如下。均值和標(biāo)準(zhǔn)差計(jì)算如下,上面的代碼是簡(jiǎn)潔方式,下面的冗長(zhǎng)方式。
> x <- c(1,2,3,4,5,6,7,8)
> mean(x) #直接用函數(shù)求平均數(shù)
[1] 4.5
> sd(x) #直接用函數(shù)求標(biāo)準(zhǔn)差
[1] 2.449490
> n <- length(x) #x中的數(shù)量
> meanx <- sum(x)/n #先求和,在算平均數(shù)
> css <- sum((x - meanx)^2) # (x – meanx)^2從 x 的每個(gè)元素中減去了4.5,然后每個(gè)元素求平方,最后計(jì)算出平方的和
> sdx <- sqrt(css / (n-1)) #平方和除以數(shù)量減1,等于42/7=6,然后求出6的平方根,即為標(biāo)準(zhǔn)差
> meanx
[1] 4.5
> sdx
[1] 2.449490
數(shù)據(jù)標(biāo)準(zhǔn)化具體使用scale()函數(shù),默認(rèn)對(duì)矩陣或數(shù)據(jù)框的指定列進(jìn)行均值為0、標(biāo)準(zhǔn)差為1的標(biāo)準(zhǔn)化。
03 概率函數(shù)
概率函數(shù)通常用來(lái)生成特征已知的模擬數(shù)據(jù),以及在用戶編寫(xiě)的統(tǒng)計(jì)函數(shù)中計(jì)算概率值。
在R中,概率函數(shù)形如 :
[dpqr]distribution_abbreviation()
其中第一個(gè)字母表示其所指分布的某一方面:
d = 密度函數(shù)(density)
p = 分布函數(shù)(distribution function)
q = 分位數(shù)函數(shù)(quantile function)
r = 生成隨機(jī)數(shù)(隨機(jī)偏差)
常用的概率函數(shù)列于表5-4中。

x <- pretty(c(-3,3), 30)
y <- dnorm(x)
plot(x, y,
type = "l",
xlab = "Normal Deviate",
ylab = "Density",
yaxs = "i"
) #繪制正態(tài)曲線

x <- pretty(c(-3,3), 30)
z<-pnorm(x)
plot(x, z,
type = "l",
xlab = "Normal Deviate",
ylab = "Distribution",
yaxs = "i"
) #繪制分布函數(shù)

> pnorm(1.96) #位于z=1.96左側(cè)的標(biāo)準(zhǔn)正態(tài)曲線下方面積是多少?
[1] 0.9750021
> qnorm(.9,mean = 500,sd=100)# 均值為 500,標(biāo)準(zhǔn)差為 100的正態(tài)分布的0.9分位點(diǎn)值為多少?
[1] 628.1552
> rnorm(50,mean = 50,sd=10) #生成 50個(gè)均值為 50,標(biāo)準(zhǔn)差為 10的正態(tài)隨機(jī)數(shù)
[1] 51.87839 45.35005 59.93238 55.93086 60.02875 45.77850
[7] 40.00659 43.05473 66.34199 53.04694 55.62084 60.13278
[13] 39.26552 44.50102 65.56196 67.33899 44.08626 50.22214
[19] 41.26078 40.60966 54.02655 53.23637 49.32678 42.60044
[25] 66.34560 61.51955 51.37980 56.66308 56.71551 53.26159
[31] 50.68065 52.63917 38.80761 51.67646 50.47654 73.45159
[37] 49.58523 57.85701 40.33247 49.27015 48.60540 52.38546
[43] 42.89752 67.62153 45.24686 44.32443 42.24713 41.93737
[49] 46.12039 48.04349
#生成0~1區(qū)間上服從正態(tài)分布的偽隨機(jī)數(shù):
> runif(5)
[1] 0.8923759 0.2876101 0.2292473 0.7666098 0.8240967
> runif(5)
[1] 0.29292497 0.04201844 0.96997523 0.21433377 0.41058722
> set.seed(1234)#顯示并指定函數(shù)使用的種子
> runif(5)
[1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
> set.seed(1234)#目的為讓重復(fù)上次的結(jié)果
> runif(5)
[1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
>
#生成多元正態(tài)數(shù)據(jù),使用MASS 包中的 mvrnorm() 函數(shù),其格式為mvrnorm(n, mean, sigma),
其中 n 是你想要的樣本大小, mean 為均值向量,而 sigma 是方差—協(xié)方差矩陣(或相關(guān)矩陣)
#生成服從多元正態(tài)分布的數(shù)據(jù)
library(MASS)
options(digits = 3)
set.seed(1234)#設(shè)定隨機(jī)數(shù)種子
mean<-c(230.7,146.7,3.6)#均值向量
sigma<-matrix(c(15360.8, 6721.2, -47.1, 6721.2,
4700.9, -16.5, -47.1, -16.5, 0.3),
nrow = 3,ncol = 3)#協(xié)方差陣
mydata<-mvrnorm(500,mean,sigma)#生成多元正態(tài)數(shù)據(jù)
mydata<-as.data.frame(mydata)#矩陣轉(zhuǎn)換為數(shù)據(jù)框
names(mydata)<-c("y","x1","x2")#對(duì)變量進(jìn)行重命名
dim(mydata)#確認(rèn)觀測(cè)的結(jié)果
head(mydata,n=10)#輸出前十個(gè)觀測(cè)結(jié)果
dim(mydata)
[1] 500 3
> head(mydata,n=10)
y x1 x2
1 98.8 41.3 3.43
2 244.5 205.2 3.80
3 375.7 186.7 2.51
4 -59.2 11.2 4.71
5 313.0 111.0 3.45
6 288.8 185.1 2.72
7 134.8 165.0 4.39
8 171.7 97.4 3.64
9 167.2 101.0 3.50
10 121.1 94.5 4.10
04. 字符處理函數(shù)
數(shù)學(xué)和統(tǒng)計(jì)函數(shù)是用來(lái)處理數(shù)值型數(shù)據(jù)的,而字符處理函數(shù)可以從文本型數(shù)據(jù)中抽取信息,設(shè)定隨機(jī)數(shù)種子指定均值向量、協(xié)方差陣生成數(shù)據(jù)查看結(jié)果或者為打印輸出和生成報(bào)告重設(shè)文本的格式。
一些最有用的字符處理函數(shù)見(jiàn)表5-6。

05.其他實(shí)用函數(shù)

06.將函數(shù)應(yīng)用于矩陣和數(shù)據(jù)框
舉例如下:
> a<-5
> sqrt(a)
[1] 2.236068
> b<-c(1.243,5.654,2.99)
> round(b)
[1] 1 6 3
> c<-matrix(runif(12),nrow = 3)
> c
[,1] [,2] [,3] [,4]
[1,] 0.96359936 0.2160280 0.2890082 0.9128172
[2,] 0.20676238 0.2396466 0.8041144 0.3533918
[3,] 0.08619744 0.1971609 0.3782496 0.9314871
> log(c)
[,1] [,2] [,3] [,4]
[1,] -0.03707967 -1.532347 -1.2413001 -0.09121962
[2,] -1.57618505 -1.428590 -0.2180137 -1.04017797
[3,] -2.45111479 -1.623735 -0.9722009 -0.07097292
> mean(c) #對(duì)c中12個(gè)元素進(jìn)行求均值
[1] 0.4648719
R中提供了一個(gè)apply()函數(shù),可將一個(gè)任意函數(shù)“應(yīng)用”到矩陣、數(shù)組、數(shù)據(jù)框的任何維度上。 apply() 函數(shù)的使用格式為:apply(x, MARGIN, FUN, ...) 其中, x為數(shù)據(jù)對(duì)象, MARGIN是維度的下標(biāo), FUN是由你指定的函數(shù),而...則包括了任何想傳
遞給FUN的參數(shù)。在矩陣或數(shù)據(jù)框中,MARGIN=1表示行,MARGIN=2表示列。
舉例如下:將一個(gè)函數(shù)應(yīng)用到矩陣的所有行(列)
> mean(c)
[1] 0.4648719
> mydata<-matrix(rnorm(30),nrow = 6)
> mydata
[,1] [,2] [,3] [,4] [,5]
[1,] 0.4585260 1.2031271 1.2338845 0.5905186 -0.2806204
[2,] -1.2611491 0.7688732 -1.8913847 -0.4351408 0.8120776
[3,] -0.5274652 0.2383510 -0.2226513 -0.2507699 -0.2077037
[4,] -0.5568142 -1.4150281 0.7681275 -0.9262694 1.4507573
[5,] -0.3744387 2.9337744 0.3879537 1.0874358 0.8414932
[6,] -0.6044000 0.9350258 0.6091330 -1.9439592 -0.8657378
> apply(mydata,1,mean)
[1] 0.6410872 -0.4013448 -0.1940478 -0.1358454 0.9752437 -0.3739876
> apply(mydata,2,mean)#對(duì)每列進(jìn)行求均值
[1] -0.4776235 0.7773539 0.1475105 -0.3130308 0.2917110
> apply(mydata,2,mean,trim=0.2)#求每列的截尾均值,最低和最高的20%均值被忽略
[1] -0.5157795 0.7863443 0.3856407 -0.2554154 0.2913117
>
5.3 數(shù)據(jù)處理難題的一套解決方案
代碼清單5-6針對(duì)本章開(kāi)始提出的問(wèn)題給出了的解決方案。
> options(digits = 2)#限定小數(shù)點(diǎn)后兩位
> Student<-c("John Davis","Angela Williams","Bullwinkle Moose",
+ "David Jones","Janice Markhamer","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)
> roster<-data.frame(Student,Math,Science,English,
+ stringsAsFactors = FALSE)#生成花名冊(cè)
> roster#輸出花名冊(cè)
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 Markhamer 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])#用scale函數(shù)把成績(jī)?nèi)坑脝挝坏臉?biāo)準(zhǔn)差來(lái)表示
> z
Math Science English
[1,] 0.013 1.078 0.587
[2,] 1.143 1.591 0.037
[3,] -1.026 -0.847 -0.697
[4,] -1.649 -0.590 -1.247
[5,] -0.068 -1.489 -0.330
[6,] 0.128 -0.205 1.137
[7,] -1.049 -0.847 -1.247
[8,] 1.432 1.078 1.504
[9,] 0.832 0.308 0.954
[10,] 0.243 -0.077 -0.697
attr(,"scaled:center")
Math Science English
501 87 22
attr(,"scaled:scale")
Math Science English
86.7 7.8 5.5
> score<-apply(z,1,mean)#計(jì)算list各行的均值
> roster<-cbind(roster,score)#把各行均值score添加到roster中
> roster
Student Math Science English score
1 John Davis 502 95 25 0.56
2 Angela Williams 600 99 22 0.92
3 Bullwinkle Moose 412 80 18 -0.86
4 David Jones 358 82 15 -1.16
5 Janice Markhamer 495 75 20 -0.63
6 Cheryl Cushing 512 85 28 0.35
7 Reuven Ytzrhak 410 80 15 -1.05
8 Greg Knox 625 95 30 1.34
9 Joel England 573 89 27 0.70
10 Mary Rayburn 522 86 18 -0.18
> y<-quantile(score,c(.8,.6,.4,.2)) #使用分位數(shù)函數(shù)求學(xué)生的綜合得分的百位分?jǐn)?shù)
> y
80% 60% 40% 20%
0.74 0.44 -0.36 -0.89
#花名冊(cè)中添加grade級(jí)別
> 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
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 Markhamer 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
> roster#加入級(jí)別變量后的花名冊(cè),并根據(jù)y的值進(jìn)行排序
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 Markhamer 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
> name<-strsplit((roster$Student)," ")#進(jìn)行字符串分割
> name
[[1]]
[1] "John" "Davis"
[[2]]
[1] "Angela" "Williams"
[[3]]
[1] "Bullwinkle" "Moose"
[[4]]
[1] "David" "Jones"
[[5]]
[1] "Janice" "Markhamer"
[[6]]
[1] "Cheryl" "Cushing"
[[7]]
[1] "Reuven" "Ytzrhak"
[[8]]
[1] "Greg" "Knox"
[[9]]
[1] "Joel" "England"
[[10]]
[1] "Mary" "Rayburn"
> Lastname<-sapply(name,"[",2)#提取列表中每個(gè)成分的第二個(gè)元素,放入一個(gè)儲(chǔ)存名字
的向量Lastname
> Firstname<-sapply(name,"[",1)#提取列表中每個(gè)成分的第一個(gè)元素,放入一個(gè)儲(chǔ)存名字
的向量Firstname
> roster<-cbind(Firstname,Lastname,roster[,-1])#把Firstname,Lastname列添加到花名冊(cè)
> roster
Firstname Lastname 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 Markhamer 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
> roster<-roster[order(Lastname,Firstname),]#對(duì)數(shù)據(jù)集按照姓和名進(jìn)行排序
> roster
Firstname Lastname Math Science English score grade
5 Janice Markhamer 495 75 20 -0.63 D
6 Cheryl Cushing 512 85 28 0.35 C
2 Angela Williams 600 99 22 0.92 A
4 David Jones 358 82 15 -1.16 F
10 Mary Rayburn 522 86 18 -0.18 C
8 Greg Knox 625 95 30 1.34 A
9 Joel England 573 89 27 0.70 B
7 Reuven Ytzrhak 410 80 15 -1.05 F
1 John Davis 502 95 25 0.56 B
3 Bullwinkle Moose 412 80 18 -0.86 D
</br>
5.4 控制流
請(qǐng)牢記以下概念:
語(yǔ)句( statement )是一條單獨(dú)的R語(yǔ)句或一組復(fù)合語(yǔ)句(包含在花括號(hào) { } 中的一組R語(yǔ)句,使用分號(hào)分隔);
條件( cond )是一條最終被解析為真( TRUE )或假( FALSE )的表達(dá)式;
表達(dá)式( expr )是一條數(shù)值或字符串的求值語(yǔ)句;
序列( seq )是一個(gè)數(shù)值或字符串序列。
01.重復(fù)和循環(huán)
循環(huán)結(jié)構(gòu)重復(fù)地執(zhí)行一個(gè)或一系列語(yǔ)句,直到某個(gè)條件不為真為止。循環(huán)結(jié)構(gòu)包括 for 和while 結(jié)構(gòu)。
- for 結(jié)構(gòu)
for 循環(huán)重復(fù)地執(zhí)行一個(gè)語(yǔ)句,直到某個(gè)變量的值不再包含在序列 seq 中為止。語(yǔ)法為:
for (var in seq) statement
比如:
> for(i in 1:10)
> print("Hello")
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
- while 結(jié)構(gòu)
while 循環(huán)重復(fù)地執(zhí)行一個(gè)語(yǔ)句,直到條件不為真為止。語(yǔ)法為:
while (cond) statement
比如:
> i<-10
> while(i>0){print("Hello");i<-i-1}
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
[1] "Hello"
值得注意的是確保while括號(hào)內(nèi)的語(yǔ)句在某個(gè)時(shí)刻不為真,否則循環(huán)將永不停止。建議聯(lián)用R中的內(nèi)建數(shù)值/字符處理函數(shù)和 apply 族函數(shù)。
2 條件執(zhí)行
在條件執(zhí)行結(jié)構(gòu)中,一條或一組語(yǔ)句僅在滿足一個(gè)指定條件時(shí)執(zhí)行。條件執(zhí)行結(jié)構(gòu)包括if-else 、 ifelse 和 switch 。
if-else 結(jié)構(gòu)
控制結(jié)構(gòu) if-else 在某個(gè)給定條件為真時(shí)執(zhí)行語(yǔ)句。也可以同時(shí)在條件為假時(shí)執(zhí)行另外的語(yǔ)句。語(yǔ)法為:
if (cond) statement
if (cond) statement1 else statement2ifelse 結(jié)構(gòu)
ifelse 結(jié)構(gòu)是 if-else 結(jié)構(gòu)比較緊湊的向量化版本,其語(yǔ)法為:
ifelse(cond, statement1, statement2)
ifelse(score > 0.5, print("Passed"), print("Failed"))
outcome <- ifelse (score > 0.5, "Passed", "Failed")
在程序的行為是二元時(shí),或者希望結(jié)構(gòu)的輸入和輸出均為向量時(shí),請(qǐng)使用 ifelse。switch 結(jié)構(gòu)
switch 根據(jù)一個(gè)表達(dá)式的值選擇語(yǔ)句執(zhí)行。語(yǔ)法為:
switch(expr, ...)
舉例如下:
> feelings<-c("sad","afraid")
> for(i in feelings)
+ print(switch(i,happy="I am glad you are happy",
+ afraid="There is nothing to fear",
+ sad="Cheer up",angary="Calm down now"))
[1] "Cheer up"
[1] "There is nothing to fear"
</br>
5.5 用戶自編函數(shù)
R的最大優(yōu)點(diǎn)之一就是用戶可以自行添加函數(shù)。R中的許多函數(shù)都是由已有函數(shù)構(gòu)成的。一個(gè)函數(shù)的結(jié)構(gòu)看起來(lái)大致如此:
myfunction <- function(arg1, arg2, ... ){
statements
return(object)
}
函數(shù)中的對(duì)象只在函數(shù)內(nèi)部使用。返回對(duì)象的數(shù)據(jù)類型是任意的,從標(biāo)量到列表皆可。
比如:一個(gè)使用了 switch 結(jié)構(gòu)的用戶自編函數(shù),此函數(shù)可讓用戶選擇輸出當(dāng)天日期的格式。
> mydate<-function(type="long"){
+ switch(type,
+ long=format(Sys.time(),"%A %B %d %Y"),
+ short=format(Sys.time(),"%m-%d-%y"),
+ cat(type,"is not a recognized type\n")
+ )
+ }
> mydate("long")
[1] "星期二 三月 14 2017"
> mydate("short")
[1] "03-14-17"
> mydate("medium")
medium is not a recognized type
>
warning:可以使用warning()來(lái)生成一條錯(cuò)誤信息,用message()來(lái)生成一條診斷信息,或者用stop()來(lái)停止當(dāng)前表達(dá)式的執(zhí)行并提示錯(cuò)誤。上面的例子中,cat()函數(shù)僅會(huì)在輸入的日期格式類型不匹配時(shí),用一個(gè)表達(dá)式來(lái)捕獲用戶給出的錯(cuò)誤參數(shù)值。這是針對(duì)自編函數(shù)的一個(gè)錯(cuò)誤捕獲和調(diào)試的方法。
</br>
5.6 整合與重構(gòu)
R中提供了許多用來(lái)整合(aggregate)和重塑(reshape)數(shù)據(jù)的強(qiáng)大方法。在整合數(shù)據(jù)時(shí),往往將多組觀測(cè)替換為根據(jù)這些觀測(cè)計(jì)算的描述性統(tǒng)計(jì)量。在重塑數(shù)據(jù)時(shí),則會(huì)通過(guò)修改數(shù)據(jù)的結(jié)構(gòu)(行和列)來(lái)決定數(shù)據(jù)的組織方式。
在接下來(lái)我們將使用已包含在R基本安裝中的數(shù)據(jù)框mtcars 。這個(gè)數(shù)據(jù)集描述了34種車型的設(shè)計(jì)和性能特點(diǎn)(汽缸數(shù)、排量、馬力、每加侖汽油行駛的英里數(shù)等等)。
01 轉(zhuǎn)置
轉(zhuǎn)置即反轉(zhuǎn)行和列。使用函數(shù)** t()** 即可。
數(shù)據(jù)集的轉(zhuǎn)置如下示例:
> cars<-mtcars[1:5,1:4]
> cars
mpg cyl disp hp
Mazda RX4 21.0 6 160 110
Mazda RX4 Wag 21.0 6 160 110
Datsun 710 22.8 4 108 93
Hornet 4 Drive 21.4 6 258 110
Hornet Sportabout 18.7 8 360 175
> t(cars)#進(jìn)行轉(zhuǎn)置
Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
mpg 21 21 22.8 21.4 18.7
cyl 6 6 4.0 6.0 8.0
disp 160 160 108.0 258.0 360.0
hp 110 110 93.0 110.0 175.0
>
02 整合數(shù)據(jù)
在R中使用一個(gè)或多個(gè)by變量和一個(gè)預(yù)先定義好的函數(shù)來(lái)折疊(collapse)數(shù)據(jù)是比較容易的。
調(diào)用格式為:
aggregate(x, by, FUN)
其中 x 是待折疊的數(shù)據(jù)對(duì)象, by 是一個(gè)變量名組成的列表,這些變量將被去掉以形成新的觀測(cè),而 FUN 則是用來(lái)計(jì)算描述性統(tǒng)計(jì)量的標(biāo)量函數(shù),它將被用來(lái)計(jì)算新觀測(cè)中的值。
示例如下,我們將根據(jù)汽缸數(shù)和擋位數(shù)整合 mtcars 數(shù)據(jù),并返回各個(gè)數(shù)值型變量的均值。
> options(digits = 3)
> attach(mtcars)
> aggdata<-aggregate(mtcars,by=list(cyl,gear),FUN = mean,
+ na.rm=TRUE)
> aggdata
Group.1 Group.2 mpg cyl disp hp drat wt qsec vs am gear carb
1 4 3 21.5 4 120 97 3.70 2.46 20.0 1.0 0.00 3 1.00
2 6 3 19.8 6 242 108 2.92 3.34 19.8 1.0 0.00 3 1.00
3 8 3 15.1 8 358 194 3.12 4.10 17.1 0.0 0.00 3 3.08
4 4 4 26.9 4 103 76 4.11 2.38 19.6 1.0 0.75 4 1.50
5 6 4 19.8 6 164 116 3.91 3.09 17.7 0.5 0.50 4 4.00
6 4 5 28.2 4 108 102 4.10 1.83 16.8 0.5 1.00 5 2.00
7 6 5 19.7 6 145 175 3.62 2.77 15.5 0.0 1.00 5 6.00
8 8 5 15.4 8 326 300 3.88 3.37 14.6 0.0 1.00 5 6.00
>
03 reshape2包
使用install.packages("reshape2")安裝reshape2包。
- 融合
數(shù)據(jù)集的融合是將它重構(gòu)為這樣一種格式:每個(gè)測(cè)量變量獨(dú)占一行,行中帶有要唯一確定這個(gè)測(cè)量所需的標(biāo)識(shí)符變量。
舉例如下:
> ID<-c(1,1,2,2)
> Time<-c(1,2,1,2)
> X1<-c(5,3,6,2)
> X2<-c(6,5,1,4)
> mydata<-data.frame(ID,Time,X1,X2)
> mydata
ID Time X1 X2
1 1 1 5 6
2 1 2 3 5
3 2 1 6 1
4 2 2 2 4
> library(reshape2)
> md<-melt(mydata,id=c("ID","Time")) #融合,每個(gè)X1、X2需要各占一行,共計(jì)八行
> md
ID Time variable value
1 1 1 X1 5
2 1 2 X1 3
3 2 1 X1 6
4 2 2 X1 2
5 1 1 X2 6
6 1 2 X2 5
7 2 1 X2 1
8 2 2 X2 4
>

- 重鑄
dcast() 函數(shù)讀取已融合的數(shù)據(jù),并使用你提供的公式和一個(gè)(可選的)用于整合數(shù)據(jù)的函數(shù)將其重塑。調(diào)用格式為:
newdata <- dcast(md, formula, fun.aggregate) 其中的 md 為已融合的數(shù)據(jù), formula 描述了想要的最后結(jié)果,而 fun.aggregate 是(可選的)數(shù)據(jù)整合函數(shù)。

比如:
> my<-dcast(md,ID~variable,mean)# 每個(gè)觀測(cè)所有Time中在X1和X2上的均值
> my
ID X1 X2
1 1 4 5.5
2 2 4 2.5
>
</br>
總結(jié)一下
本章主要學(xué)習(xí)了數(shù)學(xué)和統(tǒng)計(jì)函數(shù)(數(shù)學(xué)函數(shù)、統(tǒng)計(jì)函數(shù)、概率函數(shù))、字符處理函數(shù)以及其它的使用函數(shù),最后將函數(shù)應(yīng)用于矩陣和數(shù)據(jù)框,解決了本章前面提出問(wèn)題。同時(shí)學(xué)了控制流——循環(huán)和條件執(zhí)行,同時(shí)簡(jiǎn)單介紹了如何進(jìn)行自編函數(shù),最后學(xué)習(xí)了折疊、整合以及重鑄數(shù)據(jù)的方法。
以上這些基本具備了進(jìn)行復(fù)雜數(shù)據(jù)分析的基礎(chǔ),通過(guò)一些案列和代碼的實(shí)踐,較好的熟悉了基本工具,但是距離掌握這些工具需要更多的實(shí)踐練習(xí)和深入學(xué)習(xí),尤其是相關(guān)函數(shù)的用法,極為重要。