Item hierarchies

knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
library(arules)
set.seed(1234)

Often, we deal with many items. For example in a supermarket there may be 10s of different types of milk and 100s of different dairy products. An item hierarchy maps detailed items to broader groups. For example, milk and yogurt are grouped in the dairy category. This information will help us analyze when rules are true for a whole category.

Item hierarchy level are stored as a column in itemInfo() in the transactions.

trans <- transactions(list(
  T1 = c("apple", "banana"),
  T2 = c("apple", "yogurt"),
  T3 = c("banana", "milk"),
  T4 = c("apple", "banana", "milk"),
  T5 = c("milk", "yogurt"),
  T6 = c("apple", "banana", "yogurt")
))
itemInfo(trans)

Initially, the transactions only contain the item labels. We can add a category as an level in the hierarchy.

category_list <- c(
  apple = "fruit", banana = "fruit",
  milk = "dairy", yogurt = "dairy"
)
itemInfo(trans)$category <- category_list[itemLabels(trans)]
itemInfo(trans)

Aggregating transactions

aggregate() replaces item labels with their group. Multiple items from the same group in one basket become a single group item.

by_category <- aggregate(trans, by = "category")
inspect(trans)
inspect(by_category)
itemFrequency(by_category)

Mine the aggregated transactions when the analysis is intended to operate only at the group level. This calculates valid quality measures for that level.

category_rules <- apriori(
  by_category,
  parameter = list(support = 0.3, confidence = 0.5, minlen = 2),
  control = list(verbose = FALSE)
)
inspect(category_rules)

Mine across hierarchy levels

addAggregate() retains items and adds group items. By default, group items are marked with an asterisk. This creates rules that cross levels.

multilevel <- addAggregate(trans, by = "category")
inspect(multilevel)

multilevel_rules <- apriori(
  multilevel,
  parameter = list(support = 0.1, confidence = 0.6, minlen = 2),
  control = list(verbose = FALSE)
)
multilevel_rules

Adding category items creates trivial rules such as {apple} => {fruit*} because the hierarchy guarantees them. filterAggregate() removes associations that contain both a detailed item and its own aggregate. This reduces the size of the rule set significantly and makes it easier to interpret.

multilevel_rules <- filterAggregate(multilevel_rules)
multilevel_rules

inspect(sort(multilevel_rules, by = "lift"))

Other vignettes



Try the arules package in your browser

Any scripts or data that you put into this service are public.

arules documentation built on Sept. 11, 2026, 9:08 a.m.