R語言高級數(shù)據(jù)管理

高級數(shù)據(jù)管理

接下來废膘,我們將講解如何自己編寫函數(shù)來完成數(shù)據(jù)處理和分析任務(wù)。首先般又,我們將探索控制程序流程的多種方式彼绷,包括循環(huán)和條件執(zhí)行語句巍佑。然后,我們將研究用戶自編函數(shù)的結(jié)構(gòu)苛预,以及在編寫完成后如何調(diào)用它們句狼。最后,我們將了解數(shù)據(jù)的整合和概述方法热某,以及數(shù)據(jù)集的重塑和重構(gòu)方法腻菇。

各種函數(shù)的講解

x <- c(1, 2, 3, 4, 5, 6, 7, 8)
mean(x)
## [1] 4.5
sd(x)
## [1] 2.44949
n <- length(x)
meanx <- sum(x)/n
css <- sum((x - meanx)**2)            
sdx <- sqrt(css / (n-1))
meanx
## [1] 4.5
sdx
## [1] 2.44949
# Listing 5.2 - Generating pseudo-random numbers from 
# a uniform distribution

runif(5)
## [1] 0.4948163 0.1447270 0.4462854 0.1817478 0.0366217
runif(5)
## [1] 0.7535536 0.7257268 0.2369725 0.3417977 0.6111466
set.seed(1234)                                                     
runif(5)
## [1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
set.seed(1234)                                                      
runif(5)
## [1] 0.1137034 0.6222994 0.6092747 0.6233794 0.8609154
# Listing 5.3 - Generating data from a multivariate 
# normal distribution

library(MASS)
options(digits=3)
set.seed(1234)

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)

mydata <- mvrnorm(500, mean, sigma)                                     
mydata <- as.data.frame(mydata)                                         
names(mydata) <- c("y", "x1", "x2")                                       

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
# Listing 5.4 - Applying functions to data objects

a <- 5
sqrt(a)
## [1] 2.24
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.9636 0.216 0.289 0.913
## [2,] 0.2068 0.240 0.804 0.353
## [3,] 0.0862 0.197 0.378 0.931
log(c)
##         [,1]  [,2]   [,3]    [,4]
## [1,] -0.0371 -1.53 -1.241 -0.0912
## [2,] -1.5762 -1.43 -0.218 -1.0402
## [3,] -2.4511 -1.62 -0.972 -0.0710
mean(c)
## [1] 0.465
# Listing 5.5 - Applying a function to the rows 
# (columns) of a matrix

mydata <- matrix(rnorm(30), nrow=6)
mydata
##        [,1]   [,2]   [,3]   [,4]   [,5]
## [1,]  0.459  1.203  1.234  0.591 -0.281
## [2,] -1.261  0.769 -1.891 -0.435  0.812
## [3,] -0.527  0.238 -0.223 -0.251 -0.208
## [4,] -0.557 -1.415  0.768 -0.926  1.451
## [5,] -0.374  2.934  0.388  1.087  0.841
## [6,] -0.604  0.935  0.609 -1.944 -0.866
apply(mydata, 1, mean)     
## [1]  0.641 -0.401 -0.194 -0.136  0.975 -0.374
apply(mydata, 2, mean) 
## [1] -0.478  0.777  0.148 -0.313  0.292
apply(mydata, 2, mean, trim=.4)   
## [1] -0.542  0.852  0.499 -0.343  0.302

一個實例

一組學(xué)生參加了數(shù)學(xué)、科學(xué)和英語考試昔馋。為了給所有學(xué)生確定一個單一的成績衡量指標(biāo)筹吐,需要將這些科目的成績組合起來。另外秘遏,你還想將前20%的學(xué)生評定為A丘薛,接下來20%的學(xué)生評定為B,依次類推邦危。最后洋侨,你希望按字母順序?qū)W(xué)生排序。
觀察此數(shù)據(jù)集倦蚪,馬上可以發(fā)現(xiàn)一些明顯的障礙希坚。首先,三科考試的成績是無法比較的陵且。由于它們的均值和標(biāo)準(zhǔn)差相去甚遠(yuǎn)裁僧,所以對它們求平均值是沒有意義的。你在組合這些考試成績之前慕购,必須將其變換為可比較的單元聊疲。其次,為了評定等級沪悲,你需要一種方法來確定某個學(xué)生在前述得分上百分比排名获洲。再次,表示姓名的字段只有一個殿如,這讓排序任務(wù)復(fù)雜化了昌妹。為了正確地將其排序,需要將姓和名拆開握截。

準(zhǔn)備數(shù)據(jù)

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)
roster <- data.frame(Student, Math, Science, English,
    stringsAsFactors=FALSE)
#knitr::kable(roster)

表格展示數(shù)據(jù)

Student Math Science English


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

數(shù)據(jù)標(biāo)準(zhǔn)化

由于數(shù)學(xué)、科學(xué)和英語考試的分值不同(均值和標(biāo)準(zhǔn)差相去甚遠(yuǎn))烂叔,在組合之前需
要先讓它們變得可以比較谨胞。一種方法是將變量進(jìn)行標(biāo)準(zhǔn)化,這樣每科考試的成績就都是用單位標(biāo)準(zhǔn)差來表示蒜鸡,而不是以原始的尺度來表示了胯努。這個過程可以使用scale() 函數(shù)來實現(xiàn):

z <- scale(roster[,2:4]) 
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)
roster <- cbind(roster, score)
knitr::kable(roster)

Student Math Science English score


John Davis 502 95 25 0.56
Angela Williams 600 99 22 0.92
Bullwinkle Moose 412 80 18 -0.86
David Jones 358 82 15 -1.16
Janice Markhammer 495 75 20 -0.63
Cheryl Cushing 512 85 28 0.35
Reuven Ytzrhak 410 80 15 -1.05
Greg Knox 625 95 30 1.34
Joel England 573 89 27 0.70
Mary Rayburn 522 86 18 -0.18

然后牢裳,可以通過函數(shù) mean() 來計算各行的均值以獲得綜合得分,并使用函數(shù)
cbind() 將其添加到花名冊中:

劃分等級

函數(shù) quantile() 給出了學(xué)生綜合得分的百分位數(shù)叶沛∑蜒叮可以看到,成績?yōu)锳的分界點為0.74灰署,B的分界點為0.44判帮,等等。

y <- quantile(score, c(.8,.6,.4,.2)) 
y
##   80%   60%   40%   20% 
##  0.74  0.44 -0.36 -0.89

通過使用邏輯運(yùn)算符溉箕,你可以將學(xué)生的百分位數(shù)排名重編碼為一個新的類別型成績
變量晦墙。下面在數(shù)據(jù)框 roster 中創(chuàng)建了變量 grade :

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"
knitr::kable(roster)

Student Math Science English score grade


John Davis 502 95 25 0.56 B
Angela Williams 600 99 22 0.92 A
Bullwinkle Moose 412 80 18 -0.86 D
David Jones 358 82 15 -1.16 F
Janice Markhammer 495 75 20 -0.63 D
Cheryl Cushing 512 85 28 0.35 C
Reuven Ytzrhak 410 80 15 -1.05 F
Greg Knox 625 95 30 1.34 A
Joel England 573 89 27 0.70 B
Mary Rayburn 522 86 18 -0.18 C

按姓和名排序

使用函數(shù) strsplit() 以空格為界把學(xué)生姓名拆分為姓氏和名字。把
strsplit() 應(yīng)用到一個字符串組成的向量上會返回一個列表:

name <- strsplit((roster$Student), " ")  
name
## [[1]]
## [1] "John"  "Davis"
## 
## [[2]]
## [1] "Angela"   "Williams"
## 
## [[3]]
## [1] "Bullwinkle" "Moose"     
## 
## [[4]]
## [1] "David" "Jones"
## 
## [[5]]
## [1] "Janice"     "Markhammer"
## 
## [[6]]
## [1] "Cheryl"  "Cushing"
## 
## [[7]]
## [1] "Reuven"  "Ytzrhak"
## 
## [[8]]
## [1] "Greg" "Knox"
## 
## [[9]]
## [1] "Joel"    "England"
## 
## [[10]]
## [1] "Mary"    "Rayburn"

使用函數(shù) sapply() 提取列表中每個成分的第一個元素肴茄,放入一個儲存名字
的向量 Firstname 晌畅,并提取每個成分的第二個元素,放入一個儲存姓氏的向量Lastname 寡痰。 "["是一個可以提取某個對象的一部分的函數(shù)——在這里它是用來提取列表 name 各成分中的第一個或第二個元素的抗楔。你將使用 cbind()把它們添加到花名冊中。由于已經(jīng)不再需要 student 變量拦坠,可以將其丟棄:

lastname <- sapply(name, "[", 2)
firstname <- sapply(name, "[", 1)
roster <- cbind(firstname,lastname, roster[,-1])

最后连躏,可以使用函數(shù) order() 依姓氏和名字對數(shù)據(jù)集進(jìn)行排序:

roster <- roster[order(lastname,firstname),]
knitr::kable(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

控制流

條件語句和循環(huán)語句

循環(huán)

1.for循環(huán)

for(i in 1:5)
  print("Hello")
## [1] "Hello"
## [1] "Hello"
## [1] "Hello"
## [1] "Hello"
## [1] "Hello"

2.while循環(huán)

i <- 5
while(i > 0){
  print("Hello")
  i <- i - 1
}
## [1] "Hello"
## [1] "Hello"
## [1] "Hello"
## [1] "Hello"
## [1] "Hello"

條件

1.if-else結(jié)構(gòu)

(x <- runif(1))
## [1] 0.48
if(x > 0.5){
  print("yes")
}else{
  print("no")
}
## [1] "no"

2.ifelse結(jié)構(gòu)

(x <- runif(1))
## [1] 0.11
(result <- ifelse(x > 0.5, "yes", "no"))
## [1] "no"

3.switch結(jié)構(gòu)

level <- c("poor","good","excelent")
(i <- round(runif(1,1,3)))
## [1] 2
(result <- switch(level[i],
                 poor = "you are poor",
                 good = "yes,good",
                 excelent = "very good"))
## [1] "yes,good"

用戶自編函數(shù)

R的最大優(yōu)點之一就是用戶可以自行添加函數(shù)。事實上贪婉,R中的許多函數(shù)都是由已有函數(shù)構(gòu)成的反粥。
函數(shù)中的對象只在函數(shù)內(nèi)部使用。返回對象的數(shù)據(jù)類型是任意的疲迂,從標(biāo)量到列表皆可才顿。讓我們看一個示例。
假設(shè)你想編寫一個函數(shù)尤蒿,用來計算數(shù)據(jù)對象的集中趨勢和散布情況郑气。此函數(shù)應(yīng)當(dāng)可以選擇性地給出參數(shù)統(tǒng)計量(均值和標(biāo)準(zhǔn)差)和非參數(shù)統(tǒng)計量(中位數(shù)和絕對中位差)。結(jié)果應(yīng)當(dāng)以一個含名稱列表的形式給出腰池。另外尾组,用戶應(yīng)當(dāng)可以選擇是否自動輸出結(jié)果。除非另外指定示弓,否則此函數(shù)的默認(rèn)行為應(yīng)當(dāng)是計算參數(shù)統(tǒng)計量并且不輸出結(jié)果讳侨。

mystats <- function(x, parametric=TRUE, print=FALSE) {
  if (parametric) {
    center <- mean(x); spread <- sd(x) 
  } else {
    center <- median(x); spread <- mad(x) 
  }
  if (print & parametric) {
    cat("Mean=", center, "\n", "SD=", spread, "\n")
  } else if (print & !parametric) {
    cat("Median=", center, "\n", "MAD=", spread, "\n")
  }
  result <- list(center=center, spread=spread)
  return(result)
}
# trying it out
set.seed(1234)
x <- rnorm(500) 
y <- mystats(x)
y <- mystats(x, parametric=FALSE, print=TRUE)
## Median= -0.021 
##  MAD= 1
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市奏属,隨后出現(xiàn)的幾起案子跨跨,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,686評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勇婴,死亡現(xiàn)場離奇詭異忱嘹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)耕渴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,668評論 3 385
  • 文/潘曉璐 我一進(jìn)店門拘悦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人橱脸,你說我怎么就攤上這事础米。” “怎么了慰技?”我有些...
    開封第一講書人閱讀 158,160評論 0 348
  • 文/不壞的土叔 我叫張陵椭盏,是天一觀的道長。 經(jīng)常有香客問我吻商,道長掏颊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,736評論 1 284
  • 正文 為了忘掉前任艾帐,我火速辦了婚禮乌叶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘柒爸。我一直安慰自己准浴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,847評論 6 386
  • 文/花漫 我一把揭開白布捎稚。 她就那樣靜靜地躺著乐横,像睡著了一般。 火紅的嫁衣襯著肌膚如雪今野。 梳的紋絲不亂的頭發(fā)上葡公,一...
    開封第一講書人閱讀 50,043評論 1 291
  • 那天,我揣著相機(jī)與錄音条霜,去河邊找鬼催什。 笑死,一個胖子當(dāng)著我的面吹牛宰睡,可吹牛的內(nèi)容都是我干的蒲凶。 我是一名探鬼主播,決...
    沈念sama閱讀 39,129評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼拆内,長吁一口氣:“原來是場噩夢啊……” “哼旋圆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起麸恍,我...
    開封第一講書人閱讀 37,872評論 0 268
  • 序言:老撾萬榮一對情侶失蹤灵巧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體孩等,經(jīng)...
    沈念sama閱讀 44,318評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,645評論 2 327
  • 正文 我和宋清朗相戀三年采够,在試婚紗的時候發(fā)現(xiàn)自己被綠了肄方。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,777評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡蹬癌,死狀恐怖权她,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逝薪,我是刑警寧澤隅要,帶...
    沈念sama閱讀 34,470評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站董济,受9級特大地震影響步清,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜虏肾,卻給世界環(huán)境...
    茶點故事閱讀 40,126評論 3 317
  • 文/蒙蒙 一廓啊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧封豪,春花似錦谴轮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,861評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缘琅,卻和暖如春粘都,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胯杭。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評論 1 267
  • 我被黑心中介騙來泰國打工驯杜, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人做个。 一個月前我還...
    沈念sama閱讀 46,589評論 2 362
  • 正文 我出身青樓鸽心,卻偏偏與公主長得像,于是被迫代替她去往敵國和親居暖。 傳聞我的和親對象是個殘疾皇子顽频,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,687評論 2 351

推薦閱讀更多精彩內(nèi)容