0Pricing
R Academy · Lezione

reduce(), accumulate() e walk()

Riduca le liste, costruisca risultati cumulativi e applichi effetti collaterali con walk().

reduce(), accumulate() e walk() è una lezione R Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento R Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso R Academy include 4 lezioni in totale.

Oltre map() — Altri verbi di purrr

Mentre map() applica una funzione indipendentemente a ogni elemento, alcune attività richiedono di combinare gli elementi (reduce), di accumulare i risultati intermedi o di applicare funzioni esclusivamente per i loro effetti collaterali (walk). purrr offre funzioni dedicate a ciascun caso.

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() — Ridurre una lista a un valore

reduce(.x, .f, .init) applica cumulativamente .f agli elementi di .x, da sinistra a destra, riducendo la lista a un unico valore. reduce(list(a,b,c), f) calcola 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() con .init

L'argomento .init fornisce un valore iniziale (seme). La prima chiamata diventa f(.init, x[1]). È essenziale quando la lista potrebbe essere vuota, caso in cui il risultato è .init, o quando è necessario uno stato iniziale specifico.

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() con data frame — concatenare join

Uno degli usi più potenti di reduce() consiste nell'unire una lista di data frame. Invece di scrivere left_join(left_join(df1, df2), df3), utilizzi 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() — Conservare i risultati intermedi

accumulate(.x, .f) è simile a reduce(), ma conserva tutti i valori intermedi. Restituisce un vettore o una lista della stessa lunghezza dell'input, mostrando il risultato progressivo dopo ogni passaggio.

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() per risultati passo dopo passo

accumulate() è particolarmente utile per seguire i passaggi di un algoritmo, costruire stringhe carattere per carattere o gestire qualsiasi processo in cui si desideri esaminare ogni stato intermedio, non solo il risultato finale.

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() — Effetti collaterali senza valore restituito

walk(.x, .f) applica .f a ogni elemento di .x esclusivamente per produrre effetti collaterali, come stampare, scrivere file o inviare messaggi. Restituisce .x in modo invisibile, così è possibile usarlo in una pipeline senza interrompere la catena.

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() in una pipeline

Poiché walk() restituisce .x in modo invisibile, è possibile inserirlo in una pipeline di dplyr per registrare o stampare risultati intermedi senza interrompere il flusso. Lo si può considerare un punto di intercettazione per il debug o il logging.

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() — Effetti collaterali con due input

walk2(.x, .y, .f) è la variante a due input di walk(). Un caso d'uso tipico consiste nello scrivere più data frame su file, dove .x è la lista dei data frame e .y la lista dei percorsi dei file.

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 con indice

iwalk(.x, .f) è simile a walk(), ma passa il nome o l'indice dell'elemento come secondo argomento, .y. È utile quando è necessario sapere quale elemento si sta elaborando nell'effetto collaterale.

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() — Riduzione da destra a sinistra

reduce(.x, .f, .dir='backward') (o il deprecato reduce_right()) applica la funzione da destra a sinistra: f(a, f(b, f(c, d))). Questo è importante per le operazioni non commutative, come la sottrazione o la costruzione di stringhe.

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))

Verifica rapida

Quando utilizzerebbe walk() invece di map()?

Riepilogo: reduce, accumulate, walk

Punti chiave su reduce, accumulate e walk:

  • reduce(.x, .f) — riduce una lista a un valore, da sinistra a destra; .init imposta il valore iniziale
  • reduce(list_of_dfs, left_join) — modello efficace per concatenare più join
  • accumulate(.x, .f) — è simile a reduce, ma restituisce tutti i risultati intermedi
  • walk(.x, .f) — applica una funzione per produrre effetti collaterali, come stampare, scrivere o registrare; restituisce .x
  • walk2(.x, .y, .f) — walk con due input, ad esempio data frame + percorso del file
  • iwalk(.x, .f) — walk con il nome dell'elemento come secondo argomento
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'))

Domande Frequenti

La lezione «reduce(), accumulate() e walk()» è gratuita?

Sì — il testo completo di «reduce(), accumulate() e walk()» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso R Academy, passa a CoddyKit PRO. Il corso R Academy include 4 lezioni in totale.

Cosa imparerò in «reduce(), accumulate() e walk()»?

Riduca le liste, costruisca risultati cumulativi e applichi effetti collaterali con walk(). Eserciti R Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare R Academy?

Non è richiesta alcuna esperienza precedente. R Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «reduce(), accumulate() e walk()»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione R Academy?

Sì. Ogni lezione R Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. map() e varianti tipizzate
  2. map2() e pmap() per input multipli
  3. reduce(), accumulate() e walk()
  4. keep(), discard() e filtraggio delle liste
← Torna a R Academy