Цикл 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) }
У вкладених циклах, break та next діють лише на найвнутрішній цикл, який їх містить. Щоб залишити обидва цикли в матричному прикладі, встановіть змінну flag та перевірте її також у зовнішньому циклі.
Використовуйте seq_along() для індексів. Запис for (i в 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
Фрейм даних – це список стовпців, тому звичайний цикл 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]] extracts стовпець як вектор, тоді як 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() та summarize() конвеєр, усі з яких виконують ту саму роботу без копіювання.
Цикли 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
| Завдання | Петля | Векторизований еквівалент |
|---|---|---|
| Поелементна арифметика | для кожного елемента | x * 2, x + y, x^2 |
| Застосування функції для кожного стовпця | для назв (df) | саплі(df, середнє) |
| Застосування функції для кожного рядка | для понад seq_len(nrow(df)) | застосувати(df, 1, сума) |
| Створіть список результатів | для зі списком[[i]] <- … | lapply(v, f) |
| Умовне перекодування | для з if та else | якщо(умовність, 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) |
