# Transforming Data with dplyr — R Programming

Source: https://www.geekswithgeeks.com/en/r-programming/t-dplyr

> Filter, select, mutate, summarise and group data with dplyr verbs.

## A grammar of data manipulation

**dplyr** provides a small set of **verbs** that each do one thing and combine with the pipe. **`filter()`** keeps rows matching conditions; **`select()`** chooses columns (with helpers such as `starts_with()`, `where(is.numeric)`); **`mutate()`** adds or changes columns; **`arrange()`** sorts rows (`desc()` for descending); **`summarise()`** reduces rows to summary values; and **`group_by()`** makes subsequent verbs operate **per group**, so `group_by(city) |> summarise(revenue = sum(total))` gives revenue per city. Newer syntax lets you group for a single operation with `.by = city`. Other useful verbs: `count()`, `distinct()`, `rename()`, `slice_max()`, `relocate()`, `across()` to apply the same function to many columns, and `case_when()` and `if_else()` inside `mutate`. Column names are used **without quotes** inside verbs (tidy evaluation). The same dplyr code runs on databases via dbplyr and on large data via arrow or duckplyr.

## Answering business questions with dplyr

Each pipeline reads like a description of the analysis.

```r
library(dplyr)

sales <- readr::read_rds("data/sales_clean.rds")

# revenue and order count per city, largest first
sales |>
  filter(!is.na(amount_inr)) |>
  summarise(
    orders = n(),
    revenue = sum(amount_inr),
    avg_order = mean(amount_inr),
    .by = city
  ) |>
  arrange(desc(revenue))

# monthly revenue with a size category
sales |>
  mutate(
    month = lubridate::floor_date(order_date, "month"),
    size = case_when(amount_inr >= 5000 ~ "large", amount_inr >= 1000 ~ "medium", .default = "small")
  ) |>
  count(month, size)

# top 3 orders per city
sales |>
  slice_max(amount_inr, n = 3, by = city)

# round every numeric column
sales |> mutate(across(where(is.numeric), \(x) round(x, 0)))
```

## Instructions to a careful clerk

dplyr verbs are like instructions to a clerk with a ledger: "keep only paid orders, add a GST column, group by city, total them up, sort biggest first". Each instruction is simple; together they answer real questions.

**Quiz:** What does group_by(city) |> summarise(revenue = sum(total)) produce?

- [ ] One row with total revenue
- [x] One row per city with that city's total revenue
- [ ] The original rows sorted by city
- [ ] A plot

*Answer:* One row per city with that city's total revenue. Grouping makes summarise produce one row per group.
