Цикл For в R с примерами для списка и матрицы
⚡ Умное резюме
Цикл `for` в R выполняет блок кода один раз для каждого элемента последовательности, будь то вектор, список или матрица. В этом пошаговом руководстве рассматривается каждый из этих случаев и показано, когда векторизованный код является лучшим выбором.

A для цикла Эта команда повторяет блок кода один раз для каждого элемента последовательности. Эта последовательность может быть вектором, списком, фреймом данных, матрицей или любым другим объектом, по которому может выполняться итерация в R. R чувствителен к регистру, поэтому ключевое слово всегда пишется строчными буквами. дляФигурные скобки необходимы всякий раз, когда основной текст занимает более одной строки.
Синтаксис цикла for в R
for (i in vector) { Exp }
Здесь,
R будет перебирать все переменные в векторе и выполнять вычисления, записанные внутри exp.

Давайте посмотрим несколько примеров.
Цикл For в R, пример 1: мы перебираем все элементы вектора и печатаем текущее значение.
# Create fruit vector fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana') # Create the for statement for ( i in fruit){ print(i) }
Выход:
## [1] "Apple" ## [1] "Orange" ## [1] "Passion fruit" ## [1] "Banana"
Цикл For в R, пример 2Возведите в квадрат каждое целое число от 1 до 4 и сохраните результат в списке.
# Create an empty list list <- c() # Create a for statement to populate the list for (i in seq(1, 4, by=1)) { list[[i]] <- i*i } print(list)
Выход:
## [1] 1 4 9 16
Циклы for полезны в работе с машинным обучением. Настройка параметра регуляризации подразумевает тестирование множества возможных значений и поддержаниеping Тот, который минимизирует функцию потерь, и цикл for — это простой способ пройтись по этому диапазону.
Как использовать операторы break и next в цикле for
Два ключевых слова нарушают нормальную последовательность цикла for.
- перерыв Цикл немедленно завершается, и все оставшиеся элементы пропускаются.
- следующий Отбрасывает только текущий элемент и переходит к следующему.
fruit <- c('Apple', 'Orange', 'Passion fruit', 'Banana') # break: stop at the first match for (i in fruit) { if (i == 'Passion fruit') { print('Found it, stopping here') break } print(i) } # next: skip one element and carry on for (i in fruit) { if (i == 'Orange') next print(i) }
Вложенные циклы прерывания и последующие действия применяются только к самому внутреннему циклу, который их содержит. Чтобы оставить оба цикла в примере с матрицей, установите флаговую переменную и проверьте её также во внешнем цикле.
Для индексов используйте функцию seq_along(). Выражение for (i in 1:length(x)) выглядит безобидным, но приводит к ошибке при работе с пустым объектом, поскольку 1:0 выдает последовательность 1, 0, и цикл выполняется дважды. Функция seq_along(x) возвращает пустую последовательность, поэтому цикл корректно пропускается:
for (i in seq_along(fruit)) { cat(i, fruit[i], '\n') }
Цикл for по списку
Туалетping Перебор списка работает точно так же, как и поиск.ping над вектором, за исключением того, что каждый элемент может иметь разный тип:
# Create a list with three vectors fruit <- list(Basket = c('Apple', 'Orange', 'Passion fruit', 'Banana'), Money = c(10, 12, 15), purchase = FALSE) for (p in fruit) { print(p) }
Выход:
## [1] "Apple" "Orange" "Passion fruit" "Banana" ## [1] 10 12 15 ## [1] FALSE
Цикл for по матрице
Матрица имеет два измерения: строки и столбцы, поэтому для перебора каждой ячейки требуется два вложенных цикла for: внешний для строк и внутренний для столбцов.
# Create a matrix mat <- matrix(data = seq(10, 20, by=1), nrow = 6, ncol =2) # Create the loop with r and c to iterate over the matrix for (r in 1:nrow(mat)) for (c in 1:ncol(mat)) print(paste("Row", r, "and column",c, "have values of", mat[r,c]))
Выход:
## [1] "Row 1 and column 1 have values of 10" ## [1] "Row 1 and column 2 have values of 16" ## [1] "Row 2 and column 1 have values of 11" ## [1] "Row 2 and column 2 have values of 17" ## [1] "Row 3 and column 1 have values of 12" ## [1] "Row 3 and column 2 have values of 18" ## [1] "Row 4 and column 1 have values of 13" ## [1] "Row 4 and column 2 have values of 19" ## [1] "Row 5 and column 1 have values of 14" ## [1] "Row 5 and column 2 have values of 20" ## [1] "Row 6 and column 1 have values of 15" ## [1] "Row 6 and column 2 have values of 10"
Цикл for по фрейму данных в R
DataFrame представляет собой список столбцов, поэтому обычный цикл for проходит по столбцам, а не по строкам. Обычно это именно то, что вам нужно:
df <- data.frame(a = 1:5, b = 6:10, c = 11:15) # Loop over the columns for (col in names(df)) { cat(col, 'has mean', mean(df[[col]]), '\n') }
Обратите внимание на двойную скобку. df[[col]] extracФункция `df[col]` возвращает столбец в виде вектора, тогда как `df[col]` возвращает одностолбцовый фрейм данных, который функция `mean()` не может обработать.
Туалетping над рядами. Построчная итерация возможна, но медленна, поскольку R копирует строку при каждом проходе:
for (r in seq_len(nrow(df))) { cat('Row', r, 'sums to', sum(df[r, ]), '\n') }
Для обработки данных, превышающих несколько тысяч строк, предпочтительнее использовать rowSums(df), apply(df, 1, sum) или dplyr. group_by() и summarise() Конвейер, все из которых выполняют одну и ту же работу без копирования.
Циклы for против векторизации в R
R — векторизованный язык: большинство его операторов и функций уже работают с целыми векторами сразу в скомпилированном коде C. Явный цикл, повторяющий векторизованную операцию поэлементно, будет и длиннее, и медленнее.
# Loop version squares <- c() for (i in 1:4) { squares[i] <- i * i } # Vectorized version, same result squares <- (1:4)^2
| Сложность задачи | Loop | Векторизованный эквивалент |
|---|---|---|
| Поэлементная арифметика | для каждого элемента | x * 2, x + y, x^2 |
| Примените функцию к каждому столбцу. | для всех имен (df) | sapply(df, mean) |
| Примените функцию к каждой строке. | for over seq_len(nrow(df)) | apply(df, 1, sum) |
| Составьте список результатов | для списка[[i]] <- … | lapply(v, f) |
| Условное перекодирование | для с if и else | ifelse(cond, a, b) |
Когда цикл по-прежнему является правильным решением. Используйте цикл for, если каждая итерация зависит от предыдущего результата, если вы обращаетесь к внешнему сервису или записываете файлы, или если ясность изложения важнее скорости при работе с небольшим объектом.
Если необходимо использовать цикл, выделите память заранее. Увеличение размера объекта внутри цикла заставляет R копировать его при каждом проходе. Сначала создайте его в полном размере:
# Slow: the vector is reallocated on every pass out <- c() for (i in 1:1000) out[i] <- i^2 # Fast: allocated once out <- numeric(1000) for (i in 1:1000) out[i] <- i^2
Цикл for в R: краткое справочное руководство
Все конструкции, использованные в этом руководстве, перечислены ниже:
| Цель | Code |
|---|---|
| Цикл по вектору |
for (i in v) { print(i) } |
| Безопасный цикл по индексам |
for (i in seq_along(v)) { print(v[i]) } |
| Прохождение по списку |
for (p in my_list) { print(p) } |
| Цикл по столбцам фрейма данных |
for (col in names(df)) { print(mean(df[[col]])) } |
| Цикл по матрице |
for (r in 1:nrow(m)) for (c in 1:ncol(m)) print(m[r, c]) |
| Выйдите из цикла раньше времени. |
if (condition) break
|
| Пропустить одну итерацию |
if (condition) next
|
| Предварительно выделите место для вывода |
out <- numeric(n) |
