R高級數(shù)據(jù)管理——控制流

R擁有一般現(xiàn)代編程語言中都有的標準控制結(jié)構(gòu)方妖。在學習控制流之前生宛,應該理解以下概念:

語句(statement)是一條單獨的R語句或一組復合語句(包含在花括號{ } 中的一組R語句匠襟,使用分號分隔)祟敛;
條件(cond)是一條最終被解析為真(TRUE)或假(FALSE)的表達式;
表達式(expr)是一條數(shù)值或字符串的求值語句佣蓉;
序列(seq)是一個數(shù)值或字符串序列披摄。

1. 重復與循環(huán)

1.1 for結(jié)構(gòu)

for循環(huán)重復地執(zhí)行一個語句,直到某個變量的值不再包含在序列seq中為止勇凭。

for (var in seq) statement

若要將“Hello”打印10次:

> 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!"
1.2 while結(jié)構(gòu)

while循環(huán)重復地執(zhí)行一個語句疚膊,直到條件不為真為止。

while (cond) statement

同樣虾标,我們再來重復輸出10次“Hello寓盗!”

> 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!"

需要注意的是,在處理大數(shù)據(jù)集中的行和列時璧函,R中的循環(huán)可能比較低效費時傀蚌。只要可能,最好聯(lián)用R中的內(nèi)建數(shù)值/字符處理函數(shù)和apply族函數(shù)蘸吓。這與其他的大量使用循環(huán)的語言是有區(qū)別的善炫。

2. 條件執(zhí)行

在條件執(zhí)行結(jié)構(gòu)中, 一條或一組語句僅在滿足一個指定條件時執(zhí)行库继。 條件執(zhí)行結(jié)構(gòu)包括 if-else箩艺、ifelseswitch窜醉。

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

控制結(jié)構(gòu)if-else在某個給定條件為真時執(zhí)行語句。也可以同時在條件為假時執(zhí)行另外的語句:

if (cond) statement
if (cond) statement1 else statement2
> a=5
> b=6
> if (a < b) {a <- -1
+ } else if (a == b) {a <- 0
+ } else {a <- 1}
> print(a)
[1] -1
2.2 ifelse結(jié)構(gòu)

ifelse結(jié)構(gòu)是if-else結(jié)構(gòu)比較緊湊的向量化版本艺谆,其語法為:

ifelse(cond,statement1,statement2)

condTRUE酱虎,則執(zhí)行第一個語句;若condFALSE擂涛,則執(zhí)行第二個語句。

> x <- factor(sample(letters[1:5], 10, replace = TRUE))
> x
 [1] a a c d a b d b d d
> ifelse(x %in% c("a", "b", "c"), x, factor(NA))
 [1]  1  1  3 NA  1  2 NA  2 NA NA
2.3 switch結(jié)構(gòu)
switch(expr,...)

switch根據(jù)一個表達式的值選擇語句執(zhí)行聊记。其中的...表示與expr的各種可能輸出值綁定的語句撒妈。

> feelings <- c("sad","afraid")
> for (i in feelings) 
+   print(switch(i,
+                happy = "I am happy today",
+                afraid = "There is nothing to fear",
+                sad = "cheer up",
+                angry = "calm down now"))
[1] "cheer up"
[1] "There is nothing to fear"
#當表達式(exp)匹配后續(xù)的參數(shù)名(即變量名)時,返回參數(shù)的值
> t = "r"
> switch(t,r='re',g='gr',b='bl',"error")
[1] "re"

#如果不匹配任何參數(shù)名排监,switch函數(shù)不返回任何值狰右,可以添加一個匿名的參數(shù),
#當表達式(exp)匹配不上任意一個命名參數(shù)時舆床,switch函數(shù)將返回匿名參數(shù)的值:
> t = "xs"
> switch(t,r='re',g='gr',b='bl',"error")
[1] "error"

3. 用戶自編函數(shù)

R的最大優(yōu)點之一就是用戶可以自行添加函數(shù)棋蚌。

myfunc <- function(arg1,arg2,....) 
{
statements
return(object)
}
#example1
> avg <- function(a,b){
+   c <- mean(c(a,b));
+   return(c)
+ }
> avg(3,4)
[1] 3.5
#example2
#練習一個每次學循環(huán)都要做的矩陣的乘法
matrixf <- function(a,b){
  
  row1 <- dim(a)[1]
  col1 <- dim(a)[2]
  row2 <- dim(b)[1]
  col2 <- dim(b)[2]
  
  if (col1 == row2) {
    result <- matrix(0,nrow = row1,ncol = col2)
    for (i in 1:row1)
      for (j in 1:col2)
        result[i,j] <- sum(a[i,]*b[,j])
  return(result)
    }
  else {
    print("error")
    return(0)
  }
}
> a <- matrix(10,2)
> a
     [,1]
[1,]   10
[2,]   10
> a <- (c(1:4,2))
> a
[1] 1 2 3 4 2
> a <- matrix(1:4,2)
> a
     [,1] [,2]
[1,]    1    3
[2,]    2    4
> b <- matrix(1:4,2)
> b
     [,1] [,2]
[1,]    1    3
[2,]    2    4
> matrixf(a,b)
     [,1] [,2]
[1,]    7   15
[2,]   10   22

4. 整合與重構(gòu)

R中提供了許多用來整合(aggregate)和重塑(reshape)數(shù)據(jù)的強大方法。

4.1 轉(zhuǎn)置

轉(zhuǎn)置即反轉(zhuǎn)列和行挨队,適用于矩陣和數(shù)據(jù)框谷暮,使用函數(shù)t()即可完成。

> head_cars <- head(mtcars,6)
> head_cars
                  mpg cyl disp  hp drat  wt qsec vs am gear carb
Mazda RX4          21   6  160 110  3.9 2.6   16  0  1    4    4
Mazda RX4 Wag      21   6  160 110  3.9 2.9   17  0  1    4    4
Datsun 710         23   4  108  93  3.9 2.3   19  1  1    4    1
Hornet 4 Drive     21   6  258 110  3.1 3.2   19  1  0    3    1
Hornet Sportabout  19   8  360 175  3.1 3.4   17  0  0    3    2
Valiant            18   6  225 105  2.8 3.5   20  1  0    3    1
> t(head_cars)
     Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout Valiant
mpg       21.0          21.0       22.8           21.4              18.7    18.1
cyl        6.0           6.0        4.0            6.0               8.0     6.0
disp     160.0         160.0      108.0          258.0             360.0   225.0
hp       110.0         110.0       93.0          110.0             175.0   105.0
drat       3.9           3.9        3.9            3.1               3.1     2.8
wt         2.6           2.9        2.3            3.2               3.4     3.5
qsec      16.5          17.0       18.6           19.4              17.0    20.2
vs         0.0           0.0        1.0            1.0               0.0     1.0
am         1.0           1.0        1.0            0.0               0.0     0.0
gear       4.0           4.0        4.0            3.0               3.0     3.0
carb       4.0           4.0        1.0            1.0               2.0     1.0
4.2 整合數(shù)據(jù)

在R中使用一個或多個by變量和一個預先定義好的函數(shù)來折疊(collapse)數(shù)據(jù)是比較容易的:

aggregate(x,by,FUN)

x是待折疊的數(shù)據(jù)對象
by是一個變量名組成的列表盛垦,這些變量將被去掉以形成新的觀測
FUN則是用來計算描述性統(tǒng)計量的標量函數(shù)湿弦,它將被用來計算新觀測中的值。

> detach(mtcars)
> options(digits = 3)
> attach(mtcars)
> aggdate <- aggregate(mtcars,by = list(cyl,gear),FUN=mean,na.rm = TRUE)
> print(aggdate)
  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
> detach(mtcars)

簡單解釋一下數(shù)據(jù)腾夯,Group1cyl颊埃,Group2gear,則第一行的數(shù)據(jù)表示cyl為4蝶俱、gear為3的所有車的其它變量disp班利,hp等的平均值。
這是非痴ゴ簦可怕的功能罗标,可以自由的折疊,提取數(shù)據(jù)子集积蜻。
需要注意的一點是馒稍,在使用aggregate()函數(shù)的時候,by中的變量必須在一個列表中(即使只有一個變量)浅侨。

4.3 reshape2

reshape2包是一套重構(gòu)和整合數(shù)據(jù)集的絕妙的萬能工具纽谒。我們將在下節(jié)專題介紹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末如输,一起剝皮案震驚了整個濱河市鼓黔,隨后出現(xiàn)的幾起案子央勒,更是在濱河造成了極大的恐慌,老刑警劉巖澳化,帶你破解...
    沈念sama閱讀 212,294評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崔步,死亡現(xiàn)場離奇詭異,居然都是意外死亡缎谷,警方通過查閱死者的電腦和手機井濒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來列林,“玉大人瑞你,你說我怎么就攤上這事∠3眨” “怎么了者甲?”我有些...
    開封第一講書人閱讀 157,790評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長砌创。 經(jīng)常有香客問我虏缸,道長,這世上最難降的妖魔是什么嫩实? 我笑而不...
    開封第一講書人閱讀 56,595評論 1 284
  • 正文 為了忘掉前任刽辙,我火速辦了婚禮,結(jié)果婚禮上甲献,老公的妹妹穿的比我還像新娘扫倡。我一直安慰自己,他們只是感情好竟纳,可當我...
    茶點故事閱讀 65,718評論 6 386
  • 文/花漫 我一把揭開白布撵溃。 她就那樣靜靜地躺著,像睡著了一般锥累。 火紅的嫁衣襯著肌膚如雪缘挑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,906評論 1 290
  • 那天桶略,我揣著相機與錄音语淘,去河邊找鬼。 笑死际歼,一個胖子當著我的面吹牛惶翻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鹅心,決...
    沈念sama閱讀 39,053評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼吕粗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了旭愧?” 一聲冷哼從身側(cè)響起颅筋,我...
    開封第一講書人閱讀 37,797評論 0 268
  • 序言:老撾萬榮一對情侶失蹤宙暇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后议泵,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體占贫,經(jīng)...
    沈念sama閱讀 44,250評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,570評論 2 327
  • 正文 我和宋清朗相戀三年先口,在試婚紗的時候發(fā)現(xiàn)自己被綠了型奥。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,711評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡碉京,死狀恐怖厢汹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情收夸,我是刑警寧澤,帶...
    沈念sama閱讀 34,388評論 4 332
  • 正文 年R本政府宣布血崭,位于F島的核電站卧惜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夹纫。R本人自食惡果不足惜咽瓷,卻給世界環(huán)境...
    茶點故事閱讀 40,018評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望舰讹。 院中可真熱鬧茅姜,春花似錦、人聲如沸月匣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锄开。三九已至素标,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間萍悴,已是汗流浹背头遭。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留癣诱,地道東北人计维。 一個月前我還...
    沈念sama閱讀 46,461評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像撕予,于是被迫代替她去往敵國和親鲫惶。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,595評論 2 350

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