9.1 R循环介绍

通过命令?Control可以查看R中的循环结构。循环结构中关键词forwhile,repeat,以及break,next

我们终极目是:清晰了解循环结构后,用向量化或purrr包提供的功能摆脱循环。

9.1.1 简单示例

利用循环实现1到100连续相加求和

total <- 0
for(i in 1:100){
  total <- total+i
}
print(paste0('1到100连续相加求和等于:',total))
#> [1] "1到100连续相加求和等于:5050"

# loop structure
# for (var in seq) {expr}

9.1.2 循环结构

R中有三种循环结构:

  • for

for循环是大家使用最多的循环结构,for循环的迭代次数是固定的,并且事先知道。如最开始的示例中,1连续相加到100,共计加法次数是100次。

for循环示例如下:

library(tidyverse)
df <- tibble(
  a = rnorm(10),
  b = rnorm(10),
  c = rnorm(10),
  d = rnorm(10)
)

output <- vector("double", ncol(df))  # 1. output
for (i in seq_along(df)) {            # 2. sequence
  output[[i]] <- median(df[[i]])      # 3. body
}
output
#> [1] -0.2458 -0.2873 -0.0567  0.1443

代码解释:

上面代码中 vector函数创建一个空向量带指定长度,有两个参数,第一个时向量类型(‘逻辑,’‘整数,’‘双精度,’’字符’等),第二个是向量长度 vector(length=5),类型默认是逻辑型。

seq_along可以?seq查看用法.

hadely 解释如下:

You might not have seen seq_along() before. It’s a safe version of the familiar 1:length(l), with an important difference: if you have a zero-length vector, seq_along() does the right thing:

#wrong
seq_along(c())
#> integer(0)
1:length(c())
#> [1] 1 0

# generates the integer sequence 1, 2, ..., length(along.with). (along.with is usually abbreviated to along, and  seq_along is much faster.)

循环中尽可能利用R中的向量化,比如指定output的长度,当数据量大的时候效率提升将比较明显,养成向量化的意识对提高代码效率有显著效果.

  • while

当我们不知道要循环迭代的次数时,可以考虑使用while循环结构。

示例如下:

readinteger <- function(){
  n <- readline(prompt="Please, enter your ANSWER: ")
}

response <- as.integer(readinteger())

while (response!=42) {   
  print("Sorry, the answer to whatever the question MUST be 42");
  response <- as.integer(readinteger());
}
  • Repeat

repeat循环与while循环类似。如下所示,直到满足if条件后才会跳出循环结构。

i <- 1
total <- 0
repeat{
  total <- total+i
  i <- i+1
  if(i > 100){
    print(paste0('连续相加求和等于:',total))
    break
  }
}
#> [1] "连续相加求和等于:5050"

9.1.3 循环控制

R中如何中断或退出循环呢?除了自然结束的for循环,while,repeat是如何结束的呢,在R中,我们可以通过break以及next控制循环,上一示例中我们已经看到break是如何跳出循环的。

  • next 用法
for(i in letters[1:6] ){
  if(i == "d"){
  next
  }
  print(i)
}
#> [1] "a"
#> [1] "b"
#> [1] "c"
#> [1] "e"
#> [1] "f"
  • break 用法

当条件满足时,跳出循环。

m=10 
n=10
ctr=0
mymat = matrix(0,m,n)

for(i in 1:m) {
  for(j in 1:n) {   
    if(i==j) { 
      break;
    } else {
       # you assign the values only when i<>j
      mymat[i,j] = i*j
      ctr=ctr+1
      }
  }
  print(i*j) 
}
#> [1] 1
#> [1] 4
#> [1] 9
#> [1] 16
#> [1] 25
#> [1] 36
#> [1] 49
#> [1] 64
#> [1] 81
#> [1] 100
# 共赋值多少次
print(ctr)
#> [1] 45

9.1.4 嵌套循环

嵌套循环即在循环体中再循环。

# not run
v <- vector(length = 100)
for(i in 1:10){
  for(j in 1:10){
    v[i*j] = i * j 
  }
}