4.4 for()

fot() 함수는 반복적인 작업에 유용합니다. 매번 조건을 확인하면서 조건이 허락할 때까지 반복을 합니다. for()와 유사한 반복문 함수로 while()과 repeat()가 있습니다.

일반적으로 R 전문가들은 R의 벡터 연산의 특성을 살려 처리성능을 높이려면 가급적 반복함수보다는 map()이나 apply()를 이용한 벡터기반 반복작업을 하라고 추천합니다.

for (item in vector) {반복 실행}

vector의 갯수만큼 반복됩니다. 예를 들면 1에서 5까지 있는 벡터가 있다면 1, 2, … 이런 순으로 반복이 됩니다.

# 1부터 5까지 출력
for (i in 1:5) {
  print(i)
}
#> [1] 1
#> [1] 2
#> [1] 3
#> [1] 4
#> [1] 5
# 알파벳 철자 순서대로 5개 출력, x의 각 요소를 출력
x <- LETTERS[1:5]
for (i in 1:5) {
  print(x[i])
}
#> [1] "A"
#> [1] "B"
#> [1] "C"
#> [1] "D"
#> [1] "E"

seq_along() 함수는 객체의 길이만큼 일련번호를 출력합니다. 예를 들면 x <- LETTERS[1:5]에서 객체 x의 길이는 5입니다. lenth(x)를 하면 5입니다. seq_along(x)를 실행하면 1:lenth(x)1:5까지의 일련번호가 나옵니다.

x <- LETTERS[1:5]
for (i in seq_along(x)) {
  print(x[i])
}
#> [1] "A"
#> [1] "B"
#> [1] "C"
#> [1] "D"
#> [1] "E"

주의할 점은 for 함수에서 사용된 변수 i는 이미 다른 곳에서 변수로 사용하는 경우 조심하여야 합니다. 변수 i의 값이 for 함수를 사용하면서 변경되기 때문입니다.

# for 함수에서 사용된 아이템 변수 i는 변함
i <- 55
print(i)
#> [1] 55
for (i in 1:3) {
  print(paste0(i, "입니다~"))
}
#> [1] "1입니다~"
#> [1] "2입니다~"
#> [1] "3입니다~"
print(i)
#> [1] 3

for 함수를 반복 작업 중에 강제로 종료시키려면 nextbreak를 사용합니다. next는 현재 진행중인 반복에서만 나와 다음 반복으로 넘어가는 반면, break는 for() 함수 전체에서 빠져나옵니다.

# 3미만이면 이후 명령을 실행하지 않고 다음으로 넘어가고
# 5초과이면 for 반복에서 빠져 나옴
for (i in 1:10) {
  if (i < 3) {
    next
  }
  print(i)
  if (i >= 5) {
    break
  }
}
#> [1] 3
#> [1] 4
#> [1] 5

for 함수 내에서 산출된 결과를 저장할 변수(아래 예제에서는 out)는 사전에 정의하여야 에러가능성도 낮고 속도도 빨라집니다.

means <- c(1, 30, 50)
sds <- c(1, 2, 3)
out <- vector("list", length(means))
for (i in seq_along(means)) {
  out[[i]] <- rnorm(5, means[[i]], sds[[i]])
}
print(out)
#> [[1]]
#> [1]  0.883  1.183  2.281 -0.727  2.690
#> 
#> [[2]]
#> [1] 31.0 35.1 31.1 30.5 27.9
#> 
#> [[3]]
#> [1] 53.9 52.5 49.8 47.6 47.8

for 반복문 안에 다시 for 반복문을 사용할 수 있습니다. 참고로 seq_along(x) == seq_len(length(x)) 입니다.

x <- matrix(1:6, nrow = 2, ncol = 3)
for (i in seq_len(nrow(x))) {
  for (j in seq_len(ncol(x))) {
    print(x[i, j])
  }
}
#> [1] 1
#> [1] 3
#> [1] 5
#> [1] 2
#> [1] 4
#> [1] 6