6
R語言基礎(chǔ)--循環(huán)語句
if語句
用法如下所示:
if(條件) 表達(dá)式
if(條件) 表達(dá)式1 else 表達(dá)式2
其中if語句具體就是包含下面3個元素:
- 關(guān)鍵字
if;- 條件語句的判斷結(jié)果,也就是一個邏輯值,是TRUE或FALSE;
- 執(zhí)行語句,也就是上面提到的
表達(dá)式。
if語句案例1-簡單案例
先看一個簡單的案例,代碼如下所示:
p <- 0.03 ;{
if (p <= 0.05)
print("p<=0.05!")
else print("p > 0.05!")
}
運(yùn)行結(jié)果如下所示:
p <- 0.03 ;{
+ if (p <= 0.05)
+ print("p<=0.05!")
+ else print("p > 0.05!")
+ }
[1] "p<=0.05!"
if語句案例2-函數(shù)體中添加if語句
現(xiàn)在編寫一個函數(shù),命名為priceCalulator(),這個函數(shù)的功能在于按照服務(wù)時長計算應(yīng)該收取的費(fèi)用,函數(shù)接收2個參數(shù),分別是服務(wù)時長(hours)與每小時的單價(pph),代碼如下所示:
priceCalculator <- function(hours, pph=40){
net.price <- hours*pph
round(net.price)
}
現(xiàn)在如果我們還要添加一個功能,例如有一批大客戶,如果他們的服務(wù)需求時間長高于100小時,就打9折,也就是說,如果hours大于100,最后的總價乘以0.9,代碼更改如下所示:
priceCalculator <- function(hours, pph=40){
net.price <- hours*pph
if(hours > 100){
net.price <- net.price*0.9
}
round(net.price)
}
運(yùn)行結(jié)果如下所示:
priceCalculator(hours = 55)
[1] 2200
priceCalculator(hours = 110)
[1] 3960
if語句的省略形式
如果if語句的條件只有一行的話,那么就可以省略兩旁的大括號,例如前面的服務(wù)計費(fèi)案例可以改為如下形式:
if(hours > 100) net.price <- net.price*0.9
完整的代碼如下所示:
priceCalculator <- function(hours, pph=40){
net.price <- hours*pph
if(hours > 100) net.price <- net.price*0.9
round(net.price)
}
ifelse語句
if...else是if條件語句的擴(kuò)展,它的用法如下:
if(條件語句1){
表達(dá)式1
}else{表達(dá)式2
}
其中,當(dāng)
條件語句1為TRUE時,執(zhí)行表達(dá)式1,當(dāng)條件語句1為FALSE時,執(zhí)行表達(dá)式2。
還以前面的if語句中的服務(wù)費(fèi)用案例繼續(xù)說明一下,在一些國家,針對不同類型的客戶(公共組織或私有組織),除了就會的服務(wù)費(fèi)外,還會收取不同的稅(VAT),假設(shè)公共組織需要支付6%的VAT,而私有組織需要支付12%的VAT,此時可以在priceCalculator()函數(shù)中添加一個新的參數(shù)public,用于判斷組織是否是公共組織,現(xiàn)在代碼更改如下所示:
priceCalculator <- function(hours, pph=40, public = TRUE){
net.price <- hours*pph
if(hours > 100) net.price <- net.price*0.9
if(public){
tot.price <- net.price * 1.06
} else {
tot.price <- net.price * 1.12
}
round(tot.price)
}
例如同樣工作25時,對于公共和私有組織客戶的收費(fèi)是不一樣的,計算結(jié)果如下所示:
priceCalculator(25, public = TRUE)
[1] 1060
priceCalculator(25, public = FALSE)
[1] 1120
上面代碼的運(yùn)行過程就使用到了if...else...語句,如果參數(shù)public的值為TRUE,那么稅后價是總價乘以1.06,否則要乘以1.12。
對于if...else...語句的表達(dá)式而言,如果只有一行代碼,可以省略大括號,如下所示:
if(public) tot.price <- net.price * 1.06 else
tot.price <- net.price * 1.12
其中
else要放到行末,不能放到下一行的行首,這是因?yàn)橹灰粋€命令明顯沒有結(jié)束,R會自動讀取多行代碼,將它們合成一行,如果else沒有放在行末,那么R會認(rèn)為第一行代碼已經(jīng)結(jié)束,從而在執(zhí)行下一行代碼時報錯,只有當(dāng)條件表達(dá)式出現(xiàn)在函數(shù)中,并且一次性地Source整個腳本文件時,else才能出現(xiàn)在行首。
if...else...還能繼續(xù)簡化,我們可以把if理解為一個函數(shù),它的計算結(jié)果是TRUE或FALSE,因此可以把if表達(dá)式賦予一個對象,或者直接用到計算中,這里可以省略重新計算net.price的過程,直接將結(jié)果賦給tot.price`,如下所示:
tot.price <- net.price * if(public) 1.06 else 1.12
如果這么寫,R會先執(zhí)行if...else表達(dá)式,得到結(jié)果后,再乘以net.price,然后將結(jié)果賦給tot.price。
判斷選擇的向量化
還以上面的priceCalculator()函數(shù)為例說明一下,這個函數(shù)的參數(shù)是一個數(shù),而非一個向量,如果要計算一個向量就會出現(xiàn)警告信息,如下所示:
priceCalculator <- function(hours, pph=40, public = TRUE){
net.price <- hours*pph
if(hours > 100) net.price <- net.price*0.9
if(public){
tot.price <- net.price * 1.06
} else {
tot.price <- net.price * 1.12
}
round(tot.price)
}
priceCalculator(c(25, 110))
計算結(jié)果如下所示:
priceCalculator(c(25, 110))
[1] 1060 4664
Warning message:
In if (hours > 100) net.price <- net.price * 0.9 :
the condition has length > 1 and only the first element will be used
從警告信息可以看出,R會告訴我們丟失了一些信息,并且反映出了整個計算結(jié)果就是錯誤的,因此第二個客戶的最終結(jié)果應(yīng)該是4198,而非4664,如下所示:
priceCalculator(110)
[1] 4198
這是因?yàn)榫嫘畔⒅刑崾荆?code>if表達(dá)式只能處理單個值,而hours > 100返回的是兩個值,如下所示:
c (25, 110) > 100
[1] FALSE TRUE
ifelse()函數(shù)
如果使用ifelse()函數(shù)就能解決上面提到的問題,ifelse()函數(shù)接收3個參數(shù):
- 包含邏輯值的條件向量;
- 包含返回值的向量,它僅在對應(yīng)條件向量值為TRUE時才被返回;
- 另外一個包含返回值的向量,它僅在對應(yīng)條件向量為FALSE時才被返回。
ifelse案例1-簡單案例
先看一個簡單的ifelse案例,如下所示:
ifelse(c(1,3) < 2.5, 1:2, 3:4)
[1] 1 4
這行語句的運(yùn)行過程為:
- 條件表達(dá)式
c(1,3) < 2.5被解析成一個邏輯向量,計算結(jié)果為[1] TRUE FALSE; - 這個邏輯向量的第一個值為
TRUE,因此1確實(shí)小于2.5,所以結(jié)果向量的第1個元素為第2個參數(shù)的第1個元素,也就是1; - 條件向量的第2個值為
FALSE,因?yàn)?比2.5大,所以ifelse()函數(shù)將取第3個參數(shù)的第2個值(也就是4)作為結(jié)果向量的第2個元素。 - 把選出的值合成一個向量作為結(jié)果返回。
再來看一個簡單的案例:
x <- c(1,1,1,0,0,1,1)
ifelse(x != 1, 1, 0)
# 若果x的值不等于1,輸出1,否則輸出0
# [1] 0 0 0 1 1 0 0
現(xiàn)在我們更改priceCalculator()函數(shù),假設(shè)有2個客戶,服務(wù)時長分別為25小時和110小時,那么就可以采用下面的代碼完成計算:
my.hours <- c(25, 110)
my.hours*40*ifelse(my.hours > 100, 0.9, 1)
[1] 1000 3960
在上面的代碼中,ifelse()函數(shù)會計算my.hours > 100的結(jié)果,分別是FALSE和TRUE,其中,25對應(yīng)的是FALSE,那么結(jié)果就是my.hour*40*1,110對應(yīng)的是TRUE,結(jié)果就是my.hour*40*0.9。
現(xiàn)在繼續(xù)改造priceCalculator()函數(shù),例之成為真正能處理向量的函數(shù),此時需要改造public參數(shù),代碼如下所示:
priceCalculator <- function(hours, pph=40, public){
net.price <- hours*pph
net.price <- net.price * ifelse(hours > 100, 0.9, 1)
tot.price <- net.price * ifelse(public, 1.06, 1.12)
round(tot.price)
}
clients <- data.frame(
hours = c(25, 110, 125, 40),
public = c(TRUE, TRUE, FALSE, FALSE)
)
with(clients, priceCalculator(hours, public = public))
運(yùn)行結(jié)果如下所示:
with(clients, priceCalculator(hours, public = public))
[1] 1060 4198 5040 1792
ifelse案例2-在函數(shù)中添加ifelse
看一個案例,有兩個向量,分別為x和y,它們是時間序列,例如它們是每小時收集的氣溫和氣壓測量值,我們定義兩者的相關(guān)性為x和y同時上升或下降次數(shù)占總觀測數(shù)的比例(其實(shí)就是Kendall’s tau方法),也就是計算y[i+1]-y[i]1與x[i+1]-x[i]符號相同時的次數(shù)占總數(shù)i的比例,代碼如下所示:
findud <- function(v){
vud <- v[-1]-v[-length(v)]
return(ifelse(vud > 0, 1,-1))
}
udcorr <- function(x,y){
ud <- lapply(list(x,y),findud)
return(mean(ud[[1]] == ud[[2]]))
}
現(xiàn)在看一個案例,如下所示:
x <- c(5,12,13,3,6,0,1,15,16,8,88)
y <- c(4,2,3,23,6,10,11,12,6,3,2)
udcorr(x,y)
[1] 0.4
在這個案例中,x和y在10次中同時上升3次(第一次同時上升是12到13,2到3),并同時下降1次,得到的相關(guān)性估計為4/10=0.4。
這個函數(shù)的思路就是先把x和y的值編碼為1和-1,其中1代表當(dāng)前觀測值較前一個增加,-1表示減少,這個轉(zhuǎn)換過程就是通過vud <- v[-1]-v[-length(v)]這行代碼實(shí)現(xiàn)的。
其中,x[-1]-x[-11]表示的就是第2個元素減去第1個元素,第3個元素減去第2個元素等等,如下所示:
x[-1]-x[-11]
[1] 7 1 -10 3 -6 1 14 1 -8 80
return(ifelse(vud > 0, 1,-1))這個語句就是把上面的向量再轉(zhuǎn)換為1與-1,如下所示:
ifelse(x[-1]-x[-11] >0, 1, -1)
[1] 1 1 -1 1 -1 1 1 1 -1 1
接著又構(gòu)建了一個udcorr這個函數(shù)。其中ud <- lapply(list(x,y),findud)這行的功能就是,使用lapply()函數(shù)對xy構(gòu)成的這個列表使用findud函數(shù),如下所示:
list(x,y)
[[1]]
[1] 5 12 13 3 6 0 1 15 16 8 88
[[2]]
[1] 4 2 3 23 6 10 11 12 6 3 2
lapply(list(x,y),findud)
[[1]]
[1] 1 1 -1 1 -1 1 1 1 -1 1
[[2]]
[1] -1 1 1 -1 1 1 1 -1 -1 -1
最后使用return(mean(ud[[1]] == ud[[2]]))這行代碼來計算里面的均數(shù),因?yàn)?code>ud[[1]] == ud[[2]]的結(jié)果是一個邏輯向量,如下所示:
ud[[1]] == ud[[2]]
[1] FALSE TRUE FALSE FALSE FALSE TRUE TRUE FALSE TRUE FALSE
對于邏輯向量來說,TRUE就是1,F(xiàn)ALSE就是0,因此計算這個向量的均值就是計算TRUE占總向量數(shù)目的比例,如下所示:
mean(ud[[1]] == ud[[2]])
[1] 0.4
# 邏輯向量也能使用數(shù)學(xué)函數(shù),如下所示,TRUE就是1
sum(c(TRUE,TRUE,TRUE))
[1] 3
但是在R中,上面的代碼可以用diff()這個函數(shù)來進(jìn)行計算,這個函數(shù)可以對向量做“滯后”運(yùn)算,這個運(yùn)算的效果如下所示:
x
[1] 5 12 13 3 6 0 1 15 16 8 88
diff(x)
[1] 7 1 -10 3 -6 1 14 1 -8 80
從上面的結(jié)果我們可以看出來,這個滯后運(yùn)算其實(shí)就是后一個數(shù)減去前一個數(shù)。與滯后運(yùn)算相匹配的函數(shù)是sign()函數(shù),它可以將正值與負(fù)值轉(zhuǎn)換為1,-1或0,如下所示:
x
[1] 5 12 13 3 6 0 1 15 16 8 88
diff(x)
[1] 7 1 -10 3 -6 1 14 1 -8 80
sign(diff(x))
[1] 1 1 -1 1 -1 1 1 1 -1 1
因此,我們可以把undcorr()函數(shù)換一種方式寫,如下所示:
udcorr <- function(x,y){
mean(sign(diff(x))==sign(diff(y)))
}
ifelse案例3-轉(zhuǎn)換某個字符串
ifelse()可以嵌套使用,看一個案例,g是一個鮑魚的數(shù)據(jù)集,性別被編號為M、F或I(I是指Infant,幼蟲的意思),現(xiàn)在我們將這些編號轉(zhuǎn)換為1、2或3,如下所示:
g <- c("M","F","F","I","M","M","F")
g
[1] "M" "F" "F" "I" "M" "M" "F"
ifelse(g == "M",1,ifelse(g == "F",2,3))
[1] 1 2 2 3 1 1 2
上面代碼的運(yùn)行過程是這個樣子的:
- R先執(zhí)行外層的
ifelse(),其中當(dāng)g=="M"時,返回1;否則就返回ifelse(g == "F",2,3); - 當(dāng)返回的是
ifelse(g == "F",2,3),這是一個表達(dá)式,還能計算,那么如果g=="F",就返回2,否則返回3。
如果希望按照性別形成子集,那么可以使用which()函數(shù)尋找M、F或I對應(yīng)元素的編號,如下所示:
m <- which(g == "M")
f <- which(g == "F")
i <- which(g == "I")
m
[1] 1 5 6
f
[1] 2 3 7
i
[1] 4
如果想把這些子集保存在一個列表中,可以按下面的代碼操作,如下所示:
grps <- list()
for (gen in c("M","F","I")){
grps[[gen]] <- which(g == gen)
}
grps
結(jié)果如下所示:
grps
$M
[1] 1 5 6
$F
[1] 2 3 7
$I
[1] 4
嵌套if...else...表達(dá)式
有的時候需要處理大于2種的選擇,此時就需要使用嵌套if...else...嵌套語句,例如還以前面的priceCalculator()函數(shù)為例說明一下,客戶假設(shè)說有3種,私有組織,稅率為12%,公共組織稅率為6%,國外客戶為0%,現(xiàn)在改造priceCalculator()函數(shù),代碼如下所示:
priceCalculator <- function(hours, pph=40, client){
net.price <- hours*pph
if(client =='private'){
tot.price <- net.price * 1.12
} else {
if(client == 'public'){
tot.price <- net.price * 1.06
} else {
tot.price <- net.price * 1
}
}
round(tot.price)
}
priceCalculator(hours=50,client="private")
priceCalculator(hours=50,client="public")
priceCalculator(hours=50,client="abroad")
計算結(jié)果如下所示:
priceCalculator(hours=50,client="private")
[1] 2240
priceCalculator(hours=50,client="public")
[1] 2120
priceCalculator(hours=50,client="abroad")
[1] 2000
雖然代碼已經(jīng)進(jìn)行了改造,可以根據(jù)不同的客戶類型計算不同的收費(fèi),但是此時這個函數(shù)還只一次只能處理一個值,無法進(jìn)行向量化邏輯嵌套,對此,可以使用ifelse()函數(shù)進(jìn)行嵌套,如下所示:
priceCalculator <- function(hours, pph=40, client){
net.price <- hours*pph
VAT <- ifelse(client =='private', 1.12,
ifelse(client=='public', 1.06, 1))
tot.price <- net.price*VAT
round(tot.price)
}
privateData <- data.frame(
hours = c(25, 110, 125, 40),
type = c('private', 'private', 'private', 'private')
)
with(privateData, priceCalculator(hours, client = type))
publicData <- data.frame(
hours = c(25, 110, 125, 40),
type = c('public', 'public', 'public', 'public')
)
with(publicData, priceCalculator(hours, client = type))
abroadData <- data.frame(
hours = c(25, 110, 125, 40),
type = c('abroad', 'abroad', 'abroad', 'abroad')
)
with(abroadData, priceCalculator(hours, client = type))
mixData <- data.frame(
hours = c(25, 110, 125, 40),
type = c('private', 'public', 'abroad', 'abroad')
)
with(mixData, priceCalculator(hours, client = type))
運(yùn)行結(jié)果如下所示:
with(privateData, priceCalculator(hours, client = type))
[1] 1120 4928 5600 1792
publicData <- data.frame(
+ hours = c(25, 110, 125, 40),
+ type = c('public', 'public', 'public', 'public')
+ )
with(publicData, priceCalculator(hours, client = type))
[1] 1060 4664 5300 1696
abroadData <- data.frame(
+ hours = c(25, 110, 125, 40),
+ type = c('abroad', 'abroad', 'abroad', 'abroad')
+ )
with(abroadData, priceCalculator(hours, client = type))
[1] 1000 4400 5000 1600
mixData <- data.frame(
+ hours = c(25, 110, 125, 40),
+ type = c('private', 'public', 'abroad', 'abroad')
+ )
with(mixData, priceCalculator(hours, client = type))
[1] 1120 4664 5000 1600
switch處理多種選擇
if...else...嵌套語句適用于多種條件的判斷,假如判斷的條件只有1個就不需要使用if嵌套,使用switch()函數(shù)即可。
在前面的priceCalculator()函數(shù)的案例中,稅率實(shí)際上取決于客戶的類型,即公共組織、私有組織或者外國客戶,我們有3種可能,每種對應(yīng)一種特定的稅率,在這種情況下,就可以使用switch函數(shù)來簡化判斷,如下所示:
VAT <- switch(client, private=1.12, public=1.06, abroad=1)
完整代碼如下所示:
priceCalculator <- function(hours, pph=40, client){
net.price <- hours*pph
VAT <- switch(client, private=1.12, public=1.06, abroad=1)
tot.price <- net.price*VAT
round(tot.price)
}
priceCalculator(25, client='private')
priceCalculator(25, client='public')
priceCalculator(25, pph=40, 'abroad')
priceCalculator(25, pph=40, 'other')
運(yùn)行結(jié)果如下所示:
priceCalculator(25, client='private')
[1] 1120
priceCalculator(25, client='public')
[1] 1060
priceCalculator(25, pph=40, 'abroad')
[1] 1000
priceCalculator(25, pph=40, 'other')
numeric(0)
switch()函數(shù)調(diào)用的過程如下:
- 用一個單一值(Single Value)作為第1個參數(shù)(這里就是client),需要注意的是,
switch()無法處理向量化數(shù)據(jù),只能處理單一的數(shù)據(jù),因此第1個參數(shù)不能是向量; - 在第1個參數(shù)后,列出所有可能的情況及對應(yīng)的值。
- 這里需要注意的是,我們只列出了3種情況,其實(shí)第3種情況
abroad對應(yīng)的是其它情況,如果使用其它的字符口中,則無法進(jìn)行計算,后面會提到如何解這個問題。
switch()函數(shù)的第1個參數(shù)并不一定是一個特定的值,也可以是某個表達(dá)式,只要導(dǎo)出的結(jié)果是一個字符向量或數(shù)字即可,如下所示:
switch(1, 'some value', 'something else', 'some more')
[1] "some value"
switch(2, 'some value', 'something else', 'some more')
[1] "something else"
switch(3, 'some value', 'something else', 'some more')
[1] "some more"
在switch()中使用默認(rèn)值
在switch()函數(shù)的調(diào)用中,并不需要列出所有可能的情況,如果對于所有不滿足條件的判斷值,都返回同一個結(jié)果的話,可以把這個結(jié)果放在參數(shù)列表的末尾,并去掉前面的判斷值,因此可以看下面的代碼,這與ifelse調(diào)用的結(jié)果一樣:
VAT <- switch(client, private=1.12, pblic=1.06, 1)
現(xiàn)在就可以使用這個解決前面提出的那個問題了,如下所示:
priceCalculator <- function(hours, pph=40, client){
net.price <- hours*pph
VAT <- switch(client, private=1.12, public=1.06, 1)
tot.price <- net.price*VAT
round(tot.price)
}
priceCalculator(25, client='private')
priceCalculator(25, client='public')
priceCalculator(25, pph=40, 'abroad')
priceCalculator(25, pph=40, 'other')
運(yùn)行結(jié)果如下所示:
priceCalculator(25, client='private')
[1] 1120
priceCalculator(25, client='public')
[1] 1060
priceCalculator(25, pph=40, 'abroad')
[1] 1000
priceCalculator(25, pph=40, 'other')
[1] 1000
在switch()函數(shù)中的第3個參數(shù)里,把abroad=1改為1則就說明了,這是其他情況,而非僅僅是abroad這一種情況。
for 循環(huán)
for循環(huán)用法如下所示:
for (i in values){
... do someting...
}
for循環(huán)案例1-簡單案例
先看一個for循環(huán)的最簡單案例,如下所示:
for(i in 1:20){
cat(i);
cat(" ");
i=i+3;
}
運(yùn)行結(jié)果如下所示:
for(i in 1:20){
+ cat(i);
+ cat(" ");
+ i=i+3;
+ }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
從上面結(jié)果,我們可以看出,循環(huán)中處理的對象是1:20這20個數(shù),對每個數(shù)進(jìn)行操作不管循環(huán)內(nèi)部i如何變化。因此,循環(huán)體內(nèi)的i=i+3就不會對循環(huán)條件中的變量造成改變,具體執(zhí)行過程相當(dāng)于:i=1 -> i=i+3,此時i=4;-> 第一次循環(huán)結(jié)束,第二次循環(huán)開始,i=2。尤其注意,i變成4又變成2,所以打印出來的結(jié)果是,1,2,3,4….20的連續(xù)值。如果想要隨意的改變條件中的變量,可以使用while循環(huán),如下所示:
i=1
while(i<=20){
+ cat(i);
+ cat(" ");
+ i=i+3
+ }
1 4 7 10 13 16 19
for循環(huán)案例2-priceCalculator()函數(shù)
現(xiàn)在使用for循環(huán)來改造原來的priceCalculator()函數(shù),使這個函數(shù)可以一次地計算出多個客戶類型的結(jié)果,如下所示:
priceCalculator <- function(hours, pph=40, client){
net.price <- hours*pph*
ifelse(hours > 100, 0.9, 1)
VAT <- numeric(0)
for (i in client){
VAT <- c(VAT, switch(i, private=1.12, public=1.06, 1))
}
tot.price <- net.price*VAT
round(tot.price)
}
在這段代碼中,做了以下修改:
- 創(chuàng)建了一個長度為0的數(shù)值向量,即
VAT <- numeric(0); - 對向量
client中的每個值,用switch()來進(jìn)行邏輯判斷,選出對應(yīng)的VAT值; - 每次循環(huán),都將
switch()的結(jié)果放入向量VAT的末尾。
這個函數(shù)的計算結(jié)果就是向量VAT包含每個客戶對應(yīng)的稅率值,看一下計算結(jié)果:
clients <- data.frame(
hours = c(25, 110, 125, 40),
type = c('public','abroad','private','abroad')
)
clients
priceCalculator(clients$hours,client = clients$type)
計算結(jié)果如下所示:
clients
hours type
1 25 public
2 110 abroad
3 125 private
4 40 abroad
priceCalculator(clients$hours,client = clients$type)
[1] 1060 3960 5040 1600
any()與all()
使用any()和all()函數(shù)可以對某個變量進(jìn)行判斷,如下所示:
x <- 1:10
x
[1] 1 2 3 4 5 6 7 8 9 10
any(x>8)
[1] TRUE
any(x>88)
[1] FALSE
all(x>88)
[1] FALSE
all(x>0)
[1] TRUE
現(xiàn)在看一個案例,假設(shè)一個向量由若干個0或1構(gòu)成,我們想要找??其中連續(xù)出現(xiàn)1的游程(在一個0和1組成的序列中,一個由連續(xù)的0或1構(gòu)成的串稱為一個游程(run))。例如對于向量x(假設(shè)它為1,0,0,1,1,1,0,1,1),從它第4個索引處開始有長度為3的游程,而長度為2的游程分別始于第4,第5和第8索引的位置,因此現(xiàn)在我們構(gòu)建一個函數(shù),返回結(jié)果為(4,5,8),如下所示:
findruns <- function(x,k){
n <- length(x)
runs <- NULL
for (i in 1:(n-k+1)){
if (all(x[i:(i+k-1)]==1))
runs <- c(runs,i)
}
return(runs)
}
現(xiàn)在運(yùn)行這個函數(shù),如下所示:
x <- c(1,0,0,1,1,1,0,1,1)
findruns(x,3)
[1] 4
findruns(x,2)
[1] 4 5 8
findruns(x,6)
NULL