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

R擁有一般現(xiàn)代編程語言中都有的標(biāo)準(zhǔn)控制結(jié)構(gòu)。在學(xué)習(xí)控制流之前,應(yīng)該理解以下概念:

語句(statement)是一條單獨(dú)的R語句或一組復(fù)合語句(包含在花括號(hào){ } 中的一組R語句,使用分號(hào)分隔);
條件(cond)是一條最終被解析為真(TRUE)或假(FALSE)的表達(dá)式;
表達(dá)式(expr)是一條數(shù)值或字符串的求值語句;
序列(seq)是一個(gè)數(shù)值或字符串序列。

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

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

for循環(huán)重復(fù)地執(zhí)行一個(gè)語句,直到某個(gè)變量的值不再包含在序列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)重復(fù)地執(zhí)行一個(gè)語句,直到條件不為真為止。

while (cond) statement

同樣,我們再來重復(fù)輸出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ù)集中的行和列時(shí),R中的循環(huán)可能比較低效費(fèi)時(shí)。只要可能,最好聯(lián)用R中的內(nèi)建數(shù)值/字符處理函數(shù)和apply族函數(shù)。這與其他的大量使用循環(huán)的語言是有區(qū)別的。

2. 條件執(zhí)行

在條件執(zhí)行結(jié)構(gòu)中, 一條或一組語句僅在滿足一個(gè)指定條件時(shí)執(zhí)行。 條件執(zhí)行結(jié)構(gòu)包括 if-elseifelseswitch。

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

控制結(jié)構(gòu)if-else在某個(gè)給定條件為真時(shí)執(zhí)行語句。也可以同時(shí)在條件為假時(shí)執(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í)行第一個(gè)語句;若condFALSE,則執(zhí)行第二個(gè)語句。

> 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ù)一個(gè)表達(dá)式的值選擇語句執(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"
#當(dāng)表達(dá)式(exp)匹配后續(xù)的參數(shù)名(即變量名)時(shí),返回參數(shù)的值
> t = "r"
> switch(t,r='re',g='gr',b='bl',"error")
[1] "re"

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

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

R的最大優(yōu)點(diǎn)之一就是用戶可以自行添加函數(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
#練習(xí)一個(gè)每次學(xué)循環(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ù)的強(qiáng)大方法。

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中使用一個(gè)或多個(gè)by變量和一個(gè)預(yù)先定義好的函數(shù)來折疊(collapse)數(shù)據(jù)是比較容易的:

aggregate(x,by,FUN)

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

> 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等的平均值。
這是非??膳碌墓δ埽梢宰杂傻恼郫B,提取數(shù)據(jù)子集。
需要注意的一點(diǎn)是,在使用aggregate()函數(shù)的時(shí)候,by中的變量必須在一個(gè)列表中(即使只有一個(gè)變量)。

4.3 reshape2

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容