reduce(), accumulate() i walk()
Redukuj listy, twórz wyniki skumulowane i stosuj efekty uboczne za pomocą walk().
reduce(), accumulate() i walk() to bezpłatna lekcja R Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej R Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs R Academy zawiera 4 lekcji w sumie.
Poza map() — inne funkcje purrr
Funkcja map() stosuje funkcję niezależnie do każdego elementu, ale niektóre zadania wymagają operacji, które łączą elementy (reduce), gromadzą wyniki pośrednie (accumulate) lub stosują funkcje wyłącznie ze względu na efekty uboczne (walk). purrr udostępnia do każdego z tych zastosowań osobne funkcje.
library(purrr)
# Example: combining a list of numbers into a single value
nums <- list(1, 2, 3, 4, 5)
# We want: 1 + 2 + 3 + 4 + 5 = 15
# map() can't do this — it returns 5 separate results
# reduce() folds the list into one value
result <- reduce(nums, `+`)
cat('Sum via reduce:', result)reduce() — redukowanie listy do jednej wartości
reduce(.x, .f, .init) kumulacyjnie stosuje .f do elementów .x, od lewej do prawej, redukując listę do pojedynczej wartości. reduce(list(a,b,c), f) oblicza f(f(a,b),c).
library(purrr)
# reduce with max: find the overall maximum
values <- list(42, 17, 89, 55, 23)
result <- reduce(values, max)
cat('Maximum:', result, '\n')
# reduce with paste: concatenate strings
words <- list('The', 'quick', 'brown', 'fox')
reduce(words, paste)reduce() z .init
Argument .init określa wartość początkową (ziarno). Pierwsze wywołanie ma postać f(.init, x[1]). Jest to niezbędne, gdy lista może być pusta (wynikiem redukcji będzie .init) lub gdy wymagany jest konkretny stan początkowy.
library(purrr)
# Running count of elements matching a condition
data <- list(5, 12, 3, 18, 7, 15, 2)
# Count values greater than 10, starting from 0
reduce(data, function(count, x) count + (x > 10), .init = 0L)
# Also useful for string building:
reduce(c('A','B','C'), paste, sep='-', .init='START')reduce() z ramkami danych — łańcuchowe złączenia
Jednym z najbardziej użytecznych zastosowań reduce() jest łączenie listy ramek danych. Zamiast pisać left_join(left_join(df1, df2), df3), należy użyć reduce(list_of_dfs, left_join, by='key').
library(purrr)
library(dplyr)
base_df <- data.frame(id=1:3, name=c('Alice','Bob','Carol'))
scores <- data.frame(id=1:3, score=c(85,90,78))
grades <- data.frame(id=1:3, grade=c('B','A','C'))
city <- data.frame(id=1:3, city=c('NYC','LA','Chicago'))
dfs <- list(base_df, scores, grades, city)
reduce(dfs, left_join, by='id')accumulate() — zachowywanie wyników pośrednich
accumulate(.x, .f) działa podobnie jak reduce(), ale zachowuje wszystkie wartości pośrednie. Zwraca wektor (lub listę) o tej samej długości co dane wejściowe, pokazując wynik narastająco po każdym kroku.
library(purrr)
# Running sum — same as cumsum() but via accumulate
values <- c(100, 120, 95, 140, 160)
accumulate(values, `+`)
# Running maximum
accumulate(c(50, 52, 48, 55, 53, 58), max)accumulate() do uzyskiwania wyników krok po kroku
accumulate() jest szczególnie przydatna do śledzenia kolejnych kroków algorytmu, budowania ciągów znaków znak po znaku oraz wszelkich procesów, w których chcą Państwo analizować każdy stan pośredni, a nie tylko wynik końcowy.
library(purrr)
# Compound interest step by step
principal <- 1000
rates <- c(0.05, 0.05, 0.05, 0.05, 0.05) # 5% per year
accumulate(rates, function(balance, rate) {
round(balance * (1 + rate), 2)
}, .init = principal)walk() — efekty uboczne bez zwracania wyniku
walk(.x, .f) stosuje .f do każdego elementu .x wyłącznie ze względu na efekty uboczne (drukowanie, zapisywanie plików, wysyłanie komunikatów). Funkcja niewidocznie zwraca .x, dzięki czemu można używać jej w potoku bez przerywania łańcucha.
library(purrr)
# Print a summary for each dataset
datasets <- list(
mtcars = mtcars[,1:3],
iris = iris[,1:3]
)
walk(datasets, function(df) {
cat('Rows:', nrow(df), '| Cols:', ncol(df),
'| NAs:', sum(is.na(df)), '\n')
})walk() w potoku
Ponieważ walk() niewidocznie zwraca .x, można wstawić ją do potoku dplyr, aby rejestrować lub wyświetlać wyniki pośrednie bez przerywania przepływu. Można traktować ją jako punkt podglądu używany do debugowania lub rejestrowania informacji.
library(purrr)
library(dplyr)
results <- list(
East = data.frame(rep=c('A','B'), sales=c(100,120)),
West = data.frame(rep=c('C','D'), sales=c(200,190))
)
# Log each region's data, then continue processing
region_totals <- results %>%
walk(~cat('Processing:', nrow(.x), 'rows\n')) %>%
map_dbl(~sum(.x$sales))
print(region_totals)walk2() — efekty uboczne z dwoma danymi wejściowymi
walk2(.x, .y, .f) to wersja walk() przyjmująca dwa dane wejściowe. Klasyczny przypadek użycia to zapisywanie wielu ramek danych do plików, gdzie .x jest listą ramek danych, a .y — listą ścieżek plików.
library(purrr)
data_list <- list(
east = data.frame(x=1:3, y=4:6),
west = data.frame(x=7:9, y=10:12)
)
file_paths <- list(
'/tmp/east_data.csv',
'/tmp/west_data.csv'
)
# Write each data frame to its corresponding path
walk2(data_list, file_paths, function(df, path) {
write.csv(df, path, row.names=FALSE)
cat('Written:', path, '\n')
})iwalk() — walk z indeksem
iwalk(.x, .f) działa podobnie jak walk(), ale przekazuje nazwę elementu (lub indeks) jako drugi argument .y. Jest to wygodne, gdy w ramach efektu ubocznego trzeba wiedzieć, który element jest przetwarzany.
library(purrr)
region_counts <- list(East=150, West=200, North=85, South=120)
# Print each region with its rank
iwalk(region_counts, function(count, name) {
cat(name, ':', count, 'customers\n')
})reduce_right() — redukcja od prawej do lewej
reduce(.x, .f, .dir='backward') (lub wycofana funkcja reduce_right()) stosuje funkcję od prawej do lewej: f(a, f(b, f(c, d))). Ma to znaczenie w przypadku operacji nieprzemiennych, takich jak odejmowanie lub budowanie ciągów znaków.
library(purrr)
words <- c('fox','brown','quick','The')
# Left-to-right: 'The quick brown fox'
reduce(rev(words), paste)
# Right-to-left: same effect but starting from right
reduce(words, function(a, b) paste(b, a))Szybkie sprawdzenie
Kiedy należy użyć walk() zamiast map()?
Podsumowanie: reduce, accumulate, walk
Najważniejsze informacje o reduce, accumulate i walk:
reduce(.x, .f)— redukuje listę do jednej wartości (od lewej do prawej);.initustawia wartość początkowąreduce(list_of_dfs, left_join)— użyteczny wzorzec do łańcuchowego wykonywania złączeńaccumulate(.x, .f)— działa jak reduce, ale zwraca wszystkie wyniki pośredniewalk(.x, .f)— stosuje funkcję ze względu na efekty uboczne (drukowanie, zapisywanie, rejestrowanie); zwraca.xwalk2(.x, .y, .f)— walk z dwoma danymi wejściowymi (np. ramka danych + ścieżka pliku)iwalk(.x, .f)— walk przekazujący nazwę elementu jako drugi argument
library(purrr)
library(dplyr)
# reduce() joins a list of data frames, accumulate() shows interim states
monthly_sums <- c(100, 120, 95, 140, 160, 130)
cat('reduce (total): ', reduce(monthly_sums, `+`), '\n')
cat('accumulate (running):', accumulate(monthly_sums, `+`), '\n')
# walk() for side-effect logging
results <- list(a=42, b=17, c=89)
walk(results, ~cat('Value:', .x, '\n'))Ucz się R dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 43
- Lekcje
- 159
Często zadawane pytania
Czy lekcja „reduce(), accumulate() i walk()” jest bezpłatna?
Tak — pełny tekst „reduce(), accumulate() i walk()” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu R Academy, przejdź na CoddyKit PRO. Kurs R Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „reduce(), accumulate() i walk()”?
Redukuj listy, twórz wyniki skumulowane i stosuj efekty uboczne za pomocą walk(). Ćwiczysz R Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć R Academy?
Nie wymagamy żadnego doświadczenia. R Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „reduce(), accumulate() i walk()”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji R Academy?
Tak. Każda lekcja R Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- map() i warianty typowane
- map2() i pmap() dla wielu danych wejściowych
- reduce(), accumulate() i walk()
- keep(), discard() i filtrowanie list