Descriptive Statistical Analyses

WEEE Forum Fast-Tech Consumer Study

A multi-country study of fast tech purchasing, use and end-of-life behaviours among European consumers.

Authors
Affiliation

Dimitri Naczaj, Ph.D.

Éric Bonetto, Ph.D.

Published

8 September 2026

Show R code
source("R/fast-tech-shared.R")

Executive summary

This report presents descriptive findings from 10,245 respondents across 12 European countries.

  • Fast tech is widespread. Charging and lighting devices are present in 82.6% of surveyed households, while 77.6% of respondents bought at least one fast tech item during the previous 12 months (excluding e-vapes).
  • Purchase does not always translate into lasting use. Among recent buyers, 58.6% report that two to five purchased items remain in use. They broke or became defective is the most frequently reported reason for stopping use.
  • End-of-life pathways. Keeping devices at home and taking them to a recycling centre are the two most common individual responses. Disposal in household or plastic bin remains frequent, not necessarily ill-intentionned.
  • Durability offers a potential lever. 80.3% of previous buyers say they would pay more for at least some longer-lasting alternatives, although 63.9% do not currently intend to reduce their fast tech purchases.
  • Attitudes are favourable regarding fast tech buying and consumption.

1 Introduction

1.1 Context

Small and inexpensive electronic devices have become increasingly visible and easy to purchase, particularly through online marketplaces. Although these products can fulfill practical needs, their low price, limited perceived value and sometimes short period of use may encourage frequent purchasing, accumulation at home and inappropriate disposal. These patterns raise environmental, social and political questions, about resource consumption, electronic-waste prevention and the responsibilities of consumers, producers, retailers and online platforms.

The WEEE Forum and its participating members commissioned a European consumer study for International E-Waste Day 2026. The main objective is to examine fast tech consumption, such as ownership and purchasing, end-of-life decisions, motivations and influences. A second objective is to identify behavioural patterns and knowledge gaps that can feed consumer communication, collection strategies and policy recommendations.

The study covers 10,245 respondents across 12 European countries. Results are post-stratified to the age, gender and country distribution of the combined population aged 18–99. Weighting improves alignment on these observed characteristics but does not eliminate possible panel-selection, coverage or measurement bias. Comparisons therefore remain descriptive rather than causal.

The survey design, fieldwork, sample composition, weighting and data-processing procedures are documented in the methodology report.

1.2 Research Questions

The main research questions are:

  1. Fast tech consumption
    How widespread is fast tech ownership and purchasing, which product categories are most commonly acquired, and how many devices are bought and stored at home?

  2. Drivers of purchasing behaviour
    Which factors are associated with fast tech purchasing and future buying intentions?

  3. Use and end-of-life pathways
    What happens to fast tech devices after purchase? How many remain in use, why do consumers stop using them? To what extent are unused devices stored, reused, donated, sold, recycled or discarded through inappropriate waste streams?

  4. Levers for more sustainable behaviour
    Could greater durability, willingness to pay more, different replacement choices or improved collection convenience encourage consumers to reduce fast tech purchases and choose more sustainable alternatives?

  5. Knowledge and policy relevance
    How aware are consumers that fast tech products contain electronic components and that online platforms may have financial obligations for electronic-waste collection and recycling? How strongly do consumers support reduced consumption and stricter regulation about electronic waste?

2 Ownership

Show R code
household_cols <- c(
  "Household_Charging & lighting devices",
  "Household_High-tech",
  "Household_Gadgets & lifestyle items",
  "Household_E-vapes"
)

band_levels <- c("0", "1", "2 to 5", "6 to 9", "10 to 19", "20+")

detention_long <- df |>
  select(analysis_weight, all_of(household_cols)) |>
  pivot_longer(
    cols = all_of(household_cols),
    names_to = "Category",
    values_to = "Band"
  ) |>
  mutate(
    Category = str_remove(Category, "Household_"),
    Band     = factor(Band, levels = band_levels)
  )

# Ownership rates by category
detention_ownership <- detention_long |>
  group_by(Category) |>
  summarise(
    pct = weighted_mean_safe(Band != "0", analysis_weight),
    .groups = "drop"
  )

format_ownership_percent <- function(cat) percent(
  detention_ownership$pct[detention_ownership$Category == cat],
  accuracy = 0.1
)

# Combined quantities across the three non-vape categories.
# Since Q4 records ranges rather than exact counts, each respondent's combined
# quantity is represented by a minimum and a maximum.
household_non_vape_cols <- household_cols[
  household_cols != "Household_E-vapes"
]

household_band_min <- c(
  "0" = 0,
  "1" = 1,
  "2 to 5" = 2,
  "6 to 9" = 6,
  "10 to 19" = 10,
  "20+" = 20
)

household_band_max <- c(
  "0" = 0,
  "1" = 1,
  "2 to 5" = 5,
  "6 to 9" = 9,
  "10 to 19" = 19,
  "20+" = Inf
)

detention_combined_levels <- c(
  "No item",
  "Exactly 1 item",
  "Definitely 2 to 5 items",
  "Could be 2 to 5 or 6+ items",
  "Definitely 6 or more items"
)

detention_combined <- df |>
  transmute(
    analysis_weight,
    across(
      all_of(household_non_vape_cols),
      as.character
    )
  ) |>
  mutate(
    total_min = rowSums(
      across(
        all_of(household_non_vape_cols),
        \(x) unname(household_band_min[x])
      )
    ),
    total_max = rowSums(
      across(
        all_of(household_non_vape_cols),
        \(x) unname(household_band_max[x])
      )
    ),
    Combined_total = case_when(
      total_max == 0 ~ "No item",
      total_min == 1 & total_max == 1 ~ "Exactly 1 item",
      total_min >= 2 & total_max <= 5 ~ "Definitely 2 to 5 items",
      total_min > 5 ~ "Definitely 6 or more items",
      TRUE ~ "Could be 2 to 5 or 6+ items"
    ),
    Combined_total = factor(
      Combined_total,
      levels = detention_combined_levels
    )
  )

detention_combined_summary <- detention_combined |>
  group_by(Combined_total, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  arrange(Combined_total)

detention_combined_pct <- setNames(
  detention_combined_summary$pct,
  as.character(detention_combined_summary$Combined_total)
)

pct_own_non_vape <- 1 - detention_combined_pct[["No item"]]
pct_definitely_six_plus <- detention_combined_pct[[
  "Definitely 6 or more items"
]]
pct_definitely_two_five <- detention_combined_pct[[
  "Definitely 2 to 5 items"
]]
pct_possible_two_five <- pct_definitely_two_five +
  detention_combined_pct[["Could be 2 to 5 or 6+ items"]]

2.1 Items owned at home, by category

Q4. How many of the following items are currently in your household (regardless of who bought them or when)?

Fast tech items are present in the vast majority of surveyed households. Charging and lighting devices lead with 82.6% of respondents owning at least one, followed by high-tech items (69.5%) and gadgets & lifestyle items (69.4%). E-vapes are considerably less widespread, owned by 27.6% of the sample, reflecting a different usage.

Show R code
detention_long |>
  group_by(Category) |>
  summarise(
    pct = weighted_mean_safe(Band != "0", analysis_weight),
    .groups = "drop"
  ) |>
  mutate(category_type = if_else(Category == "E-vapes", "E-vapes", "Other categories")) |>
  ggplot(aes(x = reorder(Category, pct), y = pct, fill = category_type)) +
  geom_col(width = bg_bar_width) +
  geom_text(aes(label = percent(pct, accuracy = 0.1)), hjust = -0.2, size = bg_size_label / .pt) +
   scale_fill_manual(values = c("Other categories" = bg_accent,"E-vapes" = bg_ink_32), guide = "none") +
  scale_y_continuous(labels = percent_format(), expand = expansion(mult = c(0, 0.12))) +
  coord_flip() +
  labs(x = NULL, y = "% respondents owning at least one item")
Figure 1: Share of respondents with at least one fast tech item at home, by category

2.2 Quantity owned

The quantity distributions differ markedly by category. E-vapes have the highest share of non-ownership, while the modal quantity among the three other categories is generally between two and five items.

Show R code
detention_long |>
  group_by(Category, Band, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop_last"
  ) |>
  mutate(
    pct = weighted_n / sum(weighted_n),
    band_type = if_else(
      as.character(Band) == "0",
      "No item",
      "At least one item"
    )
  ) |>
  ungroup() |>
  ggplot(
    aes(
      x = Band,
      y = pct,
      fill = band_type
    )
  ) +
  geom_col(
    width = bg_bar_width
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "No item" = bg_ink_32,
      "At least one item" = bg_accent
    ),
    guide = "none"
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  facet_wrap(
    ~Category,
    ncol = 2
  ) +
  labs(
    x = "Number of items",
    y = NULL
  ) +
  theme(
    axis.text.x = element_text(
      angle = 30,
      hjust = 1
    ),
    panel.spacing.y = grid::unit(28, "pt")
  )
Figure 2: Distribution of quantities owned at home, by category

2.2.1 Combined quantity across categories, excluding e-vapes

Across charging and lighting devices, high-tech products, and gadgets and lifestyle items, 86.8% of respondents own at least one item. At least 44.1% definitely own six or more items.

Note: Because the questionnaire records a range for each category, the exact proportion owning two to five items in total cannot be identified. It lies between 14.1%, who are certainly in this range, and 37.6%, which additionally includes respondents whose category ranges could sum either to two to five or to six or more items.

Show R code
detention_combined_summary |>
  mutate(
    total_type = case_when(
      Combined_total == "No item" ~ "None",
      Combined_total == "Could be 2 to 5 or 6+ items" ~ "Range uncertainty",
      TRUE ~ "Classified total"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Combined_total),
    fill = total_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "None" = bg_ink_32,
      "Range uncertainty" = bg_blue_50,
      "Classified total" = bg_accent
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of respondents",
    y = NULL
  )
Figure 3: Combined quantity of fast tech items owned across non-vape categories

2.3 Ownership by socio-demographic characteristics

Show R code
detention_sociodemo_data <- df |>
  transmute(
    Age_group = as.character(Age_recoded_1),
    Gender_group = recode(
      as.character(Gender),
      "98" = "No answer"
    ),
    Employment_group = as.character(Employment),
    Household_size = as.numeric(Nb_household),
    analysis_weight,
    detention_any_non_vape = if_any(
      all_of(household_non_vape_cols),
      ~ as.character(.x) != "0"
    )
  )

summarise_ownership_dimension <- function(
  variable,
  dimension,
  levels
) {
  detention_sociodemo_data |>
    transmute(
      Group = as.character(
        .data[[variable]]
      ),
      analysis_weight,
      outcome = as.integer(
        detention_any_non_vape
      )
    ) |>
    filter(
      !is.na(outcome),
      Group %in% levels
    ) |>
    group_by(Group) |>
    summarise(
      n = n(),
      pct = weighted_mean_safe(outcome, analysis_weight),
      .groups = "drop"
    ) |>
    mutate(
      Dimension = dimension,
      Group = factor(
        Group,
        levels = levels
      )
    )
}

detention_overall <- weighted_mean_safe(
  detention_sociodemo_data$detention_any_non_vape,
  detention_sociodemo_data$analysis_weight
)

detention_desired_rows <- c(
  paste(
    "Age",
    sociodemographic_age_levels,
    sep = "___"
  ),
  paste(
    "Gender",
    sociodemographic_gender_levels,
    sep = "___"
  ),
  paste(
    "Employment",
    sociodemographic_employment_levels,
    sep = "___"
  )
)

detention_sociodemo_summary <- bind_rows(
  summarise_ownership_dimension(
    "Age_group",
    "Age",
    sociodemographic_age_levels
  ),
  summarise_ownership_dimension(
    "Gender_group",
    "Gender",
    sociodemographic_gender_levels
  ),
  summarise_ownership_dimension(
    "Employment_group",
    "Employment",
    sociodemographic_employment_levels
  )
) |>
  mutate(
    Dimension = factor(
      Dimension,
      levels = c(
        "Age",
        "Gender",
        "Employment"
      )
    ),
    Group_plot = paste(
      Dimension,
      as.character(Group),
      sep = "___"
    ),
    Group_plot = factor(
      Group_plot,
      levels = rev(
        detention_desired_rows
      )
    ),
    overall = detention_overall,
    comparison = if_else(
      pct >= overall,
      "At or above overall",
      "Below overall"
    )
  )

detention_household_model_data <-
  detention_sociodemo_data |>
  transmute(
    Household_size,
    analysis_weight,
    outcome = as.integer(
      detention_any_non_vape
    )
  ) |>
  drop_na()

detention_household_design <- survey::svydesign(
  ids = ~1,
  weights = ~analysis_weight,
  data = detention_household_model_data
)

detention_household_model <- survey::svyglm(
  outcome ~ Household_size,
  design = detention_household_design,
  family = quasibinomial()
)

detention_household_grid <- tibble(
  Household_size = seq(
    min(
      detention_household_model_data$
        Household_size
    ),
    max(
      detention_household_model_data$
        Household_size
    ),
    length.out = 100
  )
)

detention_household_prediction <- predict(
  detention_household_model,
  newdata = detention_household_grid,
  type = "link"
)

detention_household_prediction_fit <- as.numeric(
  detention_household_prediction
)
detention_household_prediction_se <- as.numeric(
  survey::SE(detention_household_prediction)
)

detention_household_curve <-
  detention_household_grid |>
  mutate(
    pct = plogis(
      detention_household_prediction_fit
    ),
    lower = plogis(
      detention_household_prediction_fit -
        1.96 *
          detention_household_prediction_se
    ),
    upper = plogis(
      detention_household_prediction_fit +
        1.96 *
          detention_household_prediction_se
    )
  )

detention_household_observed <-
  detention_household_model_data |>
  group_by(Household_size) |>
  summarise(
    n = n(),
    pct = weighted_mean_safe(outcome, analysis_weight),
    .groups = "drop"
  )

detention_age_young <-
  detention_sociodemo_summary |>
  filter(
    Dimension == "Age",
    Group == "18-29"
  ) |>
  pull(pct)

detention_age_old <-
  detention_sociodemo_summary |>
  filter(
    Dimension == "Age",
    Group == "65-99"
  ) |>
  pull(pct)

detention_employment_high <-
  detention_sociodemo_summary |>
  filter(Dimension == "Employment") |>
  slice_max(
    pct,
    n = 1,
    with_ties = FALSE
  )

detention_employment_low <-
  detention_sociodemo_summary |>
  filter(Dimension == "Employment") |>
  slice_min(
    pct,
    n = 1,
    with_ties = FALSE
  )

Ownership of at least one fast tech item (excluding e-vapes) is high across all socio-demographic groups. It ranges from 94.2% among respondents aged 18–29 to 80.3% among those aged 65–99. By employment status, it is highest among student respondents (96.0%) and lowest among other respondents (77.7%).

Basically, it means that almost all 18-39 years old and almost all students detain at least one fast tech item.

Note: These are population-weighted, unadjusted descriptive comparisons. Gender categories with non-substantive answers and employment respondents who preferred not to answer are excluded.

Show R code
detention_sociodemo_summary |>
  ggplot(aes(
    x = pct,
    y = Group_plot,
    colour = comparison
  )) +
  geom_vline(
    xintercept =
      detention_sociodemo_summary$
        overall[[1]],
    colour = bg_ink_32,
    linewidth = bg_lw_hairline,
    linetype = "dashed"
  ) +
  geom_segment(
    aes(
      x = overall,
      xend = pct,
      yend = Group_plot
    ),
    colour = bg_ink_32,
    linewidth = bg_lw_line
  ) +
  geom_point(size = 3) +
  geom_text(
    aes(
      label = percent(
        pct,
        accuracy = 0.1
      )
    ),
    hjust = -0.35,
    colour = bg_ink,
    size = bg_size_label / .pt
  ) +
  scale_colour_manual(
    values = c(
      "At or above overall" = bg_accent,
      "Below overall" = bg_blue
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    limits = c(0, 1),
    expand = expansion(
      mult = c(0, 0.06)
    )
  ) +
  scale_y_discrete(
    labels = \(x) {
      str_remove(x, "^.*___")
    }
  ) +
  facet_grid(
    rows = vars(Dimension),
    scales = "free_y",
    space = "free_y"
  ) +
  labs(
    x = "% owning at least one item",
    y = NULL
  ) +
  theme(
    strip.text.y = element_text(
      angle = 0
    )
  )
Figure 4: Ownership of at least one non-vape fast tech item, by socio-demographic group

Household size is treated as a continuous predictor. The curve below shows the population-weighted estimated probability of ownership, with the weighted observed rate for each household size overlaid.

Show R code
ggplot(
  detention_household_curve,
  aes(x = Household_size, y = pct)
) +
  geom_ribbon(
    aes(ymin = lower, ymax = upper),
    fill = bg_accent_20,
    alpha = bg_alpha_mute
  ) +
  geom_line(
    colour = bg_accent,
    linewidth = bg_lw_line
  ) +
  geom_point(
    data = detention_household_observed,
    colour = bg_ink,
    aes(size = n)
  ) +
  scale_size_continuous(
    name = "N",
    range = c(2, 5)
  ) +
  scale_x_continuous(
    breaks = 1:10
  ) +
  scale_y_continuous(
    labels = percent_format(),
    limits = c(0, 1),
    expand = expansion(
      mult = c(0, 0.04)
    )
  ) +
  labs(
    x = "Household size",
    y = "Estimated probability of ownership"
  )
Figure 5: Ownership of non-vape fast tech by household size. The bigger the point, the more respondents.

3 Buying Behaviour

Show R code
buying_band_levels <- c(
  "0", "1", "2 to 5", "6 to 9", "10 to 19", "20+"
)

n_total <- nrow(df)

n_ever_bought <- sum(df$Buyer == "Buyer", na.rm = TRUE)
pct_ever_bought <- weighted_mean_safe(
  df$Buyer == "Buyer",
  df$analysis_weight
)

n_recent_buyers <- sum(df$Buy_12months == "Buyer", na.rm = TRUE)
pct_recent_buyers <- weighted_mean_safe(
  df$Buy_12months == "Buyer",
  df$analysis_weight
)

Non-buyers are respondents who declared never having bought any fast tech device.

3.1 Buyers demographics

Show R code
buyer_demographics_data <- df |>
  transmute(
    Buyer_group = recode(
      Buyer,
      "Buyer" = "Buyers",
      "Non buyer" = "Non-buyers"
    ),
    Age = as.numeric(Age),
    Gender = as.character(Gender),
    Country,
    analysis_weight,
    Income = coalesce(
      Income_Norway,
      Income_Romania,
      Income_Poland,
      Income_Switzerland,
      Income_UK,
      Income_Euro
    )
  ) |>
  group_by(Country) |>
  mutate(
    income_lower = income_lower_bound(Income),
    income_bracket_position =
      assign_income_bracket_position(
        Country,
        income_lower
      ),
    income_n_brackets = n_distinct(
      income_lower,
      na.rm = TRUE
    ),
    income_eur_equivalent = case_when(
      is.na(income_lower) ~ NA_real_,
      Country == "Switzerland" &
        income_bracket_position == income_n_brackets ~ 135000,
      TRUE ~ 5000 +
        (income_bracket_position - 1) * 10000
    )
  ) |>
  ungroup()

buyer_demographics_summary <- buyer_demographics_data |>
  filter(!is.na(Buyer_group)) |>
  group_by(Buyer_group) |>
  summarise(
    n = n(),
    age_mean = weighted_mean_safe(Age, analysis_weight),
    age_sd = weighted_sd_safe(Age, analysis_weight),
    income_median = weighted_quantile_safe(
      income_eur_equivalent, analysis_weight, probs = 0.5
    ),
    income_q1 = weighted_quantile_safe(
      income_eur_equivalent, analysis_weight, probs = 0.25
    ),
    income_q3 = weighted_quantile_safe(
      income_eur_equivalent, analysis_weight, probs = 0.75
    ),
    .groups = "drop"
  )

buyer_gender_summary <- buyer_demographics_data |>
  filter(
    Gender %in% c(
      "Female",
      "Male",
      "Non-binary"
    )
  ) |>
  group_by(Buyer_group, Gender) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop_last"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  ungroup()

buyer_demographics_design <- survey::svydesign(
  ids = ~1,
  weights = ~analysis_weight,
  data = buyer_demographics_data |>
    mutate(Buyer_binary = as.integer(Buyer_group == "Buyers"))
)

buyer_age_test <- survey::svyttest(
  Age ~ Buyer_binary,
  design = subset(
    buyer_demographics_design,
    !is.na(Age) & !is.na(Buyer_binary)
  )
)

buyer_gender_test <- survey::svychisq(
  ~Buyer_group + Gender,
  design = subset(
    buyer_demographics_design,
    Gender %in% c("Female", "Male")
  ),
  statistic = "F"
)

buyer_age_gender_model_data <- buyer_demographics_data |>
  filter(
    !is.na(Age),
    !is.na(Buyer_group),
    Gender %in% c("Female", "Male")
  ) |>
  mutate(
    Buyer_binary = as.integer(Buyer_group == "Buyers"),
    Gender = factor(Gender, levels = c("Female", "Male")),
    Age_centered = Age - weighted_mean_safe(Age, analysis_weight)
  )

buyer_age_gender_design <- survey::svydesign(
  ids = ~1,
  weights = ~analysis_weight,
  data = buyer_age_gender_model_data
)

buyer_age_gender_model <- survey::svyglm(
  Buyer_binary ~ Age_centered * Gender,
  design = buyer_age_gender_design,
  family = quasibinomial()
)

buyer_age_gender_interaction_test <- survey::regTermTest(
  buyer_age_gender_model,
  ~Age_centered:Gender
)

buyer_age_gender_interaction_p <- as.numeric(
  buyer_age_gender_interaction_test$p
)[1]

buyer_income_test <- survey::svyranktest(
  income_eur_equivalent ~ Buyer_binary,
  design = subset(
    buyer_demographics_design,
    !is.na(income_eur_equivalent) & !is.na(Buyer_binary)
  ),
  test = "wilcoxon"
)

buyer_age_mean <- setNames(
  buyer_demographics_summary$age_mean,
  buyer_demographics_summary$Buyer_group
)

buyer_income_median <- setNames(
  buyer_demographics_summary$income_median,
  buyer_demographics_summary$Buyer_group
)

buyer_income_q1 <- setNames(
  buyer_demographics_summary$income_q1,
  buyer_demographics_summary$Buyer_group
)

buyer_income_q3 <- setNames(
  buyer_demographics_summary$income_q3,
  buyer_demographics_summary$Buyer_group
)

buyer_female_pct <- setNames(
  buyer_gender_summary$pct[
    buyer_gender_summary$Gender == "Female"
  ],
  buyer_gender_summary$Buyer_group[
    buyer_gender_summary$Gender == "Female"
  ]
)

buyer_group_colours <- c(
  "Buyers" = bg_accent,
  "Non-buyers" = bg_blue
)

buyer_age_gender_data <- buyer_demographics_data |>
  filter(
    !is.na(Age),
    Gender %in% c(
      "Female",
      "Male"
    )
  ) |>
  mutate(
    Buyer_group = factor(
      Buyer_group,
      levels = c(
        "Buyers",
        "Non-buyers"
      )
    ),
    group_y = case_when(
      Buyer_group == "Buyers" ~ 1,
      Buyer_group == "Non-buyers" ~ 2
    ),
    gender_direction = if_else(
      Gender == "Female",
      1,
      -1
    ),
    box_y = group_y +
      gender_direction * 0.13
  )

buyer_age_axis_labels <- buyer_age_gender_data |>
  count(Buyer_group, name = "n") |>
  mutate(
    axis_label = paste0(
      Buyer_group,
      "\nN = ",
      format_count(n)
    )
  ) |>
  select(
    Buyer_group,
    axis_label
  ) |>
  deframe()

buyer_age_gender_density <- buyer_age_gender_data |>
  group_by(
    Buyer_group,
    Gender,
    group_y,
    gender_direction
  ) |>
  group_modify(
    \(.x, .y) {
      density_estimate <- density(
        .x$Age,
        weights = .x$analysis_weight / sum(.x$analysis_weight),
        from = 18,
        to = 90,
        n = 512
      )

      tibble(
        Age = density_estimate$x,
        density = density_estimate$y
      )
    }
  ) |>
  ungroup() |>
  mutate(
    density_height =
      density / max(density) * 0.38,
    density_y = group_y +
      gender_direction * density_height
  )

buyer_age_gender_means <- buyer_age_gender_data |>
  group_by(Buyer_group, Gender) |>
  summarise(
    Age = weighted_mean_safe(Age, analysis_weight),
    box_y = first(box_y),
    .groups = "drop"
  )

Buyers are younger than non-buyers: their mean age is 47.7 years, compared with 59.5 years among non-buyers (p < .001). Women account for 50.2% of buyers and 59.3% of non-buyers; buyer status also differs by gender (p < .001). The age gradient does not differ significantly between women and men (p = 0.799).

Show R code
ggplot() +
  geom_hline(
    yintercept = c(1, 2),
    colour = bg_ink_32,
    linewidth = bg_lw_hairline
  ) +
  geom_ribbon(
    data = buyer_age_gender_density,
    aes(
      x = Age,
      ymin = group_y,
      ymax = density_y,
      fill = Buyer_group,
      alpha = Gender,
      group = interaction(
        Buyer_group,
        Gender
      )
    ),
    colour = NA
  ) +
  geom_boxplot(
    data = buyer_age_gender_data,
    aes(
      x = Age,
      y = box_y,
      weight = analysis_weight,
      group = interaction(
        Buyer_group,
        Gender
      )
    ),
    orientation = "y",
    width = 0.09,
    outlier.shape = NA,
    fill = bg_surface,
    colour = bg_ink,
    alpha = 0.85,
    linewidth = bg_lw_hairline
  ) +
  geom_point(
    data = buyer_age_gender_means,
    aes(
      x = Age,
      y = box_y
    ),
    shape = 21,
    size = 2.8,
    stroke = 0.7,
    fill = bg_surface,
    colour = bg_ink
  ) +
  scale_fill_manual(
    values = buyer_group_colours,
    guide = "none"
  ) +
  scale_alpha_manual(
    name = NULL,
    breaks = c(
      "Female",
      "Male"
    ),
    labels = c(
      "Women (above)",
      "Men (below)"
    ),
    values = c(
      "Female" = 0.78,
      "Male" = 0.34
    ),
    guide = guide_legend(
      override.aes = list(
        fill = bg_accent,
        colour = NA
      )
    )
  ) +
  scale_x_continuous(
    breaks = seq(0, 90, by = 10),
    limits = c(0, 90),
    expand = expansion(mult = c(0.01, 0.01))
  ) +
  scale_y_continuous(
    breaks = c(1, 2),
    labels = c(
      buyer_age_axis_labels[["Buyers"]],
      buyer_age_axis_labels[["Non-buyers"]]
    ),
    limits = c(0.55, 2.45),
    expand = expansion(mult = c(0, 0))
  ) +
  labs(
    x = "Age",
    y = NULL,
    caption = str_wrap(
      paste(
        "Women: above centre line; men: below.",
        "White circles: means; boxes: medians and IQRs."
      ),
      width = 88
    )
  ) +
  theme(
    panel.grid.major.y = element_blank(),
    panel.grid.minor = element_blank(),
    legend.position = "top"
  )
Figure 6: Age distribution of buyers and non-buyers, by gender

The median approximate income bracket is €35k in both groups, but the buyers’ distribution is shifted towards higher brackets: its middle 50% ranges from €25k to €55k, compared with €15k to €45k among non-buyers (p < .001). It means that, overall, buyers seem to have higher revenues.

3.2 Ever bought fast tech

Q5. Have you ever bought small and inexpensive electronic devices, excluding e-vapes?

Fast tech purchasing is widespread in the surveyed population. Overall, 9,154 respondents (87.4%) have bought fast tech at least once, while 1,091 (12.6%) report never having bought these products.

Show R code
buyer_status <- df |>
  filter(!is.na(Buyer)) |>
  group_by(Buyer) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    Status = recode(
      Buyer,
      "Buyer" = "Ever bought fast tech",
      "Non buyer" = "Never bought fast tech"
    ),
    pct = weighted_n / sum(weighted_n)
  )

buyer_status |>
  ggplot(aes(x = reorder(Status, pct), y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.2,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  coord_flip() +
  labs(x = NULL, y = "% of respondents")
Figure 7: Respondents who have ever bought fast tech

3.3 Purchased during the last 12 months

Show R code
recent_purchase_long <- df |>
  select(analysis_weight, all_of(recent_purchase_cols)) |>
  pivot_longer(
    cols = all_of(recent_purchase_cols),
    names_to = "Category",
    values_to = "Band"
  ) |>
  mutate(
    Category = str_remove(Category, "^Buy_12months_"),
    Band = factor(
      as.character(Band),
      levels = buying_band_levels
    )
  )

recent_purchase_summary <- recent_purchase_long |>
  group_by(Category) |>
  summarise(
    n_respondents = sum(!is.na(Band)),
    n_bought = sum(Band != "0", na.rm = TRUE),
    pct = weighted_mean_safe(Band != "0", analysis_weight),
    .groups = "drop"
  )

recent_purchase_combined_levels <- c(
  "No purchase",
  "Exactly 1 item",
  "Definitely 2 to 5 items",
  "Could be 2 to 5 or 6+ items",
  "Definitely 6 or more items"
)

recent_purchase_combined <- df |>
  transmute(
    analysis_weight,
    across(
      all_of(recent_purchase_cols),
      as.character
    )
  ) |>
  mutate(
    total_min = rowSums(
      across(
        all_of(recent_purchase_cols),
        \(x) unname(household_band_min[x])
      )
    ),
    total_max = rowSums(
      across(
        all_of(recent_purchase_cols),
        \(x) unname(household_band_max[x])
      )
    ),
    Combined_total = case_when(
      total_max == 0 ~ "No purchase",
      total_min == 1 & total_max == 1 ~ "Exactly 1 item",
      total_min >= 2 & total_max <= 5 ~ "Definitely 2 to 5 items",
      total_min > 5 ~ "Definitely 6 or more items",
      TRUE ~ "Could be 2 to 5 or 6+ items"
    ),
    Combined_total = factor(
      Combined_total,
      levels = recent_purchase_combined_levels
    )
  )

recent_purchase_combined_summary <- recent_purchase_combined |>
  group_by(Combined_total, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  arrange(Combined_total)

recent_purchase_combined_pct <- setNames(
  recent_purchase_combined_summary$pct,
  as.character(recent_purchase_combined_summary$Combined_total)
)

pct_no_recent_purchase <- recent_purchase_combined_pct[["No purchase"]]
pct_exactly_one_recent_purchase <- recent_purchase_combined_pct[[
  "Exactly 1 item"
]]
pct_definitely_six_plus_recent_purchase <- recent_purchase_combined_pct[[
  "Definitely 6 or more items"
]]
pct_definitely_two_five_recent_purchase <- recent_purchase_combined_pct[[
  "Definitely 2 to 5 items"
]]
pct_possible_two_five_recent_purchase <-
  pct_definitely_two_five_recent_purchase +
  recent_purchase_combined_pct[["Could be 2 to 5 or 6+ items"]]

Q3. How many of the following items did you personally buy, over the last 12 months?

8,205 respondents (77.6%) purchased at least one fast tech item during the previous 12 months (August 2025 - July 2026).

Charging and lighting devices are most bought (68.0% of respondents), while gadgets and lifestyle items (57.5%) and high-tech products (51.9%) were bought by a little over half of the respondents.

Note: since e-vapes are banned from most european countries, we didn’t ask the question about this category

Show R code
recent_purchase_summary |>
  ggplot(aes(x = reorder(Category, pct), y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.2,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    limits = c(0, NA),
    expand = expansion(mult = c(0, 0.12))
  ) +
  coord_flip() +
  labs(
    x = NULL,
    y = "% of all respondents"
  )
Figure 8: Share of respondents who purchased fast tech during the last 12 months, by category

3.4 Quantity purchased

Charging and lighting devices have the highest overall purchasing rate, with 32.8% of respondents having bought 2 to 5 items during the past year.

Show R code
recent_purchase_long |>
  group_by(Category, Band, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop_last"
  ) |>
  mutate(
    pct = weighted_n / sum(weighted_n),
    band_type = if_else(
      as.character(Band) == "0",
      "No purchase",
      "At least one purchase"
    )
  ) |>
  ungroup() |>
  ggplot(
    aes(
      x = Band,
      y = pct,
      fill = band_type
    )
  ) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(
      label = if_else(
        pct >= 0.02,
        percent(pct, accuracy = 0.1),
        ""
      )
    ),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "No purchase" = bg_ink_32,
      "At least one purchase" = bg_accent
    ),
    guide = "none"
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.13))
  ) +
  facet_wrap(
    ~Category,
    ncol = 1
  ) +
  labs(
    x = "Number of items purchased",
    y = "% of respondents"
  ) +
  theme(
    axis.text.x = element_text(
      angle = 30,
      hjust = 1
    ),
    panel.spacing.y = grid::unit(32, "pt")
  )
Figure 9: Number of fast tech items purchased during the last 12 months, by category

3.4.1 Combined quantity across fast tech categories

About 77.6% of respondents bought at least one fast tech item during the last 12 months (excluding e-vapes). 10.8% bought exactly one item, while at least 20.1% bought six or more.

The exact share buying two to five items in total lies between 18.9% and 46.7%, depending on the exact counts within the ranges selected for each category.

Note: Q3 uses quantity ranges for each category. Combined totals therefore preserve the resulting uncertainty rather than imputing an exact number within each range.

Show R code
recent_purchase_combined_summary |>
  mutate(
    total_type = case_when(
      Combined_total == "No purchase" ~ "None",
      Combined_total == "Could be 2 to 5 or 6+ items" ~ "Range uncertainty",
      TRUE ~ "Classified total"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Combined_total),
    fill = total_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "None" = bg_ink_32,
      "Range uncertainty" = bg_blue_50,
      "Classified total" = bg_accent
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of respondents",
    y = NULL
  )
Figure 10: Combined quantity of fast tech items purchased during the last 12 months

3.5 Buying intention, by item category

Show R code
intention_cols <- c(
  "Charging & lighting devices_Intend to buy",
  "High-tech_Intend to buy",
  "Gadgets & lifestyle items_Intend to buy"
)

intention_summary <- df |>
  select(analysis_weight, all_of(intention_cols)) |>
  pivot_longer(
    cols = all_of(intention_cols),
    names_to = "Category",
    values_to = "Intention"
  ) |>
  filter(!is.na(Intention)) |>
  mutate(
    Category = str_remove(Category, "_Intend to buy$")
  ) |>
  group_by(Category) |>
  summarise(
    n_presented = n(),
    n_intended = sum(Intention == "Intended"),
    pct = weighted_mean_safe(Intention == "Intended", analysis_weight),
    .groups = "drop"
  )

intention_percent_by_category <- setNames(
  intention_summary$pct,
  intention_summary$Category
)

Q8/Q9. Let’s talk about the most recent [Category A/B] you bought. Q8a/Q9a. Did you intend to buy it?

Buying intentions are high for all three product categories. Among respondents to whom the category was presented, 77.8% intended to buy charging and lighting devices, 78.4% intended to buy high-tech products, and 75.1% intended to buy gadgets and lifestyle items.

Show R code
intention_summary |>
  ggplot(aes(x = reorder(Category, pct), y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.2,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    limits = c(0, 1),
    expand = expansion(mult = c(0, 0.08))
  ) +
  coord_flip() +
  labs(
    x = NULL,
    y = "% intending to buy"
  )
Figure 11: Intention to buy fast tech items

3.6 Buying reasons

Show R code
item_categories <- c(
  "Charging & lighting devices",
  "High-tech",
  "Gadgets & lifestyle items"
)

item_reason_suffixes <- c(
  "For work, study or everyday use",
  "As a temporary replacement",
  "I wanted a newer version",
  "As a spare device",
  "I bought it even though I didn't really need it",
  "It was a gift for someone else",
  "There was no other product / no other choice",
  "Other"
)

item_reason_cols <- unlist(
  lapply(
    item_categories,
    \(category) paste0(category, "_", item_reason_suffixes)
  ),
  use.names = FALSE
)

item_reason_summary <- df |>
  select(analysis_weight, all_of(item_reason_cols)) |>
  pivot_longer(
    cols = all_of(item_reason_cols),
    names_to = "Variable",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Category = str_extract(Variable, "^[^_]+"),
    Reason = str_remove(Variable, "^[^_]+_"),
    selected = is_selected(Value)
  ) |>
  group_by(Category, Reason) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    Reason_plot = str_wrap(Reason, width = 36)
  )

item_reason_combined_summary <- df |>
  mutate(respondent_id = row_number()) |>
  select(
    respondent_id,
    analysis_weight,
    all_of(item_reason_cols)
  ) |>
  pivot_longer(
    cols = all_of(item_reason_cols),
    names_to = "Variable",
    values_to = "Value"
  ) |>
  mutate(
    Reason = str_remove(
      Variable,
      "^[^_]+_"
    ),
    presented = !is.na(Value),
    selected = is_selected(Value)
  ) |>
  group_by(
    respondent_id,
    Reason
  ) |>
  summarise(
    analysis_weight = first(analysis_weight),
    presented = any(presented),
    selected = any(selected),
    .groups = "drop"
  ) |>
  filter(presented) |>
  group_by(Reason) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct)) |>
  mutate(
    Reason_plot = str_wrap(
      Reason,
      width = 42
    )
  )

item_reason_combined_pct <- setNames(
  item_reason_combined_summary$pct,
  item_reason_combined_summary$Reason
)

format_item_reason_percent <- function(
  category,
  reason
) {
  format_percent(
    item_reason_summary$pct[
      item_reason_summary$Category == category &
        item_reason_summary$Reason == reason
    ]
  )
}

Q8b/Q9b. Why did you buy it?

Reasons differ by category, even though fast tech items are mostly bought for use, as a replacement or as a spare device. High-tech items are more often reported as purchases motivated by wanting a newer version (28.7%), while gadgets and lifestyle items are more often reported as purchases made without a real need (18.3%).

Note: these were multiple-response questions, so respondents could select more than one reason and percentages do not sum to 100%.

Show R code
item_reason_summary |>
  mutate(
    Reason_plot = str_wrap(Reason, width = 42)
  ) |>
  ggplot(
    aes(
      x = pct,
      y = fct_reorder(Reason_plot, pct)
    )
  ) +
  geom_col(
    width = 0.52,
    fill = bg_accent
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  scale_y_discrete(
    expand = expansion(add = 0.35)
  ) +
  facet_wrap(
    ~Category,
    ncol = 1,
    scales = "free_y"
  ) +
  labs(
    x = "% selecting the reason",
    y = NULL
  ) +
  theme(
    axis.text.y = element_text(
      lineheight = 0.9
    ),
    panel.spacing.y = grid::unit(32, "pt")
  )
Figure 12: Reasons for buying or intending to buy fast tech, by item category

3.6.1 Combined buying reasons across item categories

When the three fast tech categories are combined, having a temporary replacement is the most widely reported buying reason (40.0%). This is followed by buying an item as a spare device (39.6%), for work, study or everyday use (36.4%), and wanting a newer version (34.4%).

Nearly a quarter of recent buyers selected buying an item despite not really needing it (22.7%), for at least one category.

Note: Each reason is counted no more than once per respondent, even when it was selected for several categories. Respondents could select multiple reasons, so the percentages do not sum to 100%.

Show R code
item_reason_combined_summary |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Reason_plot, pct)
  )) +
  geom_col(
    width = bg_bar_width,
    fill = bg_accent
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of eligible recent buyers",
    y = NULL
  )
Figure 13: Buying reasons across all non-vape fast tech categories

3.7 General reasons for buying fast tech

Show R code
general_reason_cols <- c(
  "They are more affordable",
  "They are the only available option",
  "They are easily available or showcased",
  "I read positive reviews about them",
  "Promotions or special deals",
  "People I trust recommend them",
  "I see them in ads or on social media",
  "Curiosity, for fun, or trying something new",
  "Other...88",
  "I don’t know...89"
)

general_reason_summary <- df |>
  select(analysis_weight, all_of(general_reason_cols)) |>
  pivot_longer(
    cols = all_of(general_reason_cols),
    names_to = "Reason",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Reason = recode(
      Reason,
      "Other...88" = "Other",
      "I don’t know...89" = "I don’t know"
    ),
    selected = is_selected(Value)
  ) |>
  group_by(Reason) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct)) |>
  mutate(
    Reason_plot = str_wrap(Reason, width = 38)
  )

general_reason_percent <- setNames(
  general_reason_summary$pct,
  general_reason_summary$Reason
)

Q10. Generally speaking, what makes you buy small and inexpensive electronic devices rather than more expensive alternatives?

Half of respondents designated price as a purchasing driver (55.2%). Together with promotions (35.8%), this makes affordability the leading reported reason Availability or product visibility is the second reason (28.5%).

Social influences seem to have a smaller impact: positive reviews by 21.2%, recommendations from trusted people by 15.9%, and advertising or social media by 11.8%.

Note: this was also a multiple-response question.

Show R code
general_reason_summary |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Reason_plot, pct)
  )) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of respondents who have ever bought fast tech",
    y = NULL
  )
Figure 14: General reasons for buying fast tech

3.8 Purchase channels

Show R code
purchase_channel_cols <- c(
  "On the brand’s website",
  "Online stores, marketplaces, social media",
  "Tobacconist, convenience store",
  "Physical stores, outdoor stall, market store",
  "At the airport or a train station",
  "As gifts, professional giveaways or merch",
  "Second hand platform",
  "I don’t remember...99",
  "Other...98"
)

purchase_channel_summary <- df |>
  select(analysis_weight, all_of(purchase_channel_cols)) |>
  pivot_longer(
    cols = all_of(purchase_channel_cols),
    names_to = "Channel",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Channel = recode(
      Channel,
      "I don’t remember...99" = "I don’t remember",
      "Other...98" = "Other"
    ),
    selected = is_selected(Value)
  ) |>
  group_by(Channel) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct)) |>
  mutate(
    Channel_plot = str_wrap(Channel, width = 40)
  )

purchase_channel_pct <- setNames(
  purchase_channel_summary$pct,
  purchase_channel_summary$Channel
)

Q11. Where do you usually get your small and inexpensive electronic devices (no matter the category)?

Online stores, marketplaces and social media are the most frequently reported purchase channels, selected by 52.1% of buyers. Physical stores, outdoor stalls and market stores follow closely (48.0%), while 25.2% buy directly from brand websites. All other channels were selected by fewer than one buyer in seven.

Note: Respondents could select more than one purchase channel, so percentages do not sum to 100%.

Show R code
purchase_channel_summary |>
  mutate(
    response_type = if_else(
      Channel %in% c("I don’t remember", "Other"),
      "Non-substantive response",
      "Purchase channel"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Channel_plot, pct),
    fill = response_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Purchase channel" = bg_accent,
      "Non-substantive response" = bg_ink_32
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of buyers",
    y = NULL
  )
Figure 15: Usual channels for obtaining fast tech devices

3.9 Fast tech items still in use today

Show R code
still_use_summary <- df |>
  filter(
    Buy_12months == "Buyer",
    !is.na(`12months_still use`)
  ) |>
  mutate(
    Band = factor(
      as.character(`12months_still use`),
      levels = buying_band_levels
    )
  ) |>
  group_by(Band, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n))

still_use_percent_by_band <- setNames(
  still_use_summary$pct,
  as.character(still_use_summary$Band)
)

Q12. Among all the small and inexpensive electronic devices you’ve bought during the last 12 months, how many do you still personally use today?

Among respondents who purchased fast tech during the last 12 months, 58.6% report that two to five items are still in use; 20.7% report one item, while 3.4% report that none of the items are still in use.

Note: we’ve only asked about the items recently bought (less than a year).

Show R code
still_use_summary |>
  ggplot(aes(x = Band, y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(
    x = "Number of items still in use",
    y = "% of respondents who purchased fast tech\nin the last 12 months"
  )
Figure 16: Number of fast tech items purchased during the last 12 months that are still in use

3.10 Shortest duration of use

Show R code
shortest_use_levels <- c(
  "I got rid of it without ever using it",
  "Single-use",
  "Less than a week",
  "Less than a month",
  "1 to 6 months",
  "6 to 12 months",
  "12 months or more",
  "I don’t know / don’t remember"
)

shortest_use_summary <- summarise_response_distribution(
  df,
  "Shortest_used",
  shortest_use_levels
)

pct_shortest_under_month <- shortest_use_summary |>
  filter(
    Response %in% c(
      "I got rid of it without ever using it",
      "Single-use",
      "Less than a week",
      "Less than a month"
    )
  ) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

shortest_use_pct <- setNames(
  shortest_use_summary$pct,
  as.character(shortest_use_summary$Response)
)

pct_shortest_within_six_months <-
  pct_shortest_under_month +
  shortest_use_pct[["1 to 6 months"]]

Q13. Think about the small and inexpensive electronic devices you’ve ever had (excluding disposable e-cigarettes). What is the shortest period of time you have used one of them before discarding it?

More than a third of previous buyers (38.6%) recalled their shortest-lived fast tech device was discarded without being used, after a single use or within one month. Overall, 57.9% declared that their shortest-lived fast tech device lasted no more than six months.

Show R code
shortest_use_summary |>
  mutate(
    response_type = if_else(
      Response == "I don’t know / don’t remember",
      "Don’t know",
      "Reported duration"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Response),
    fill = response_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Reported duration" = bg_accent,
      "Don’t know" = bg_ink_32
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  scale_y_discrete(
    labels = \(x) str_wrap(x, width = 38)
  ) +
  labs(
    x = "% of previous buyers",
    y = NULL
  )
Figure 17: Shortest recalled period of use before discarding a fast tech device

4 End-of-Life Behaviour

Show R code
eol_band_levels <- c(
  "0", "1", "2 to 5", "6 to 9", "10 to 19", "20+"
)

4.1 Items disposed of during the last 12 months

Show R code
disposed_long <- df |>
  select(analysis_weight, all_of(disposed_cols)) |>
  pivot_longer(
    all_of(disposed_cols),
    names_to = "Category",
    values_to = "Code"
  ) |>
  filter(!is.na(Code)) |>
  mutate(
    Category = str_remove(
      Category,
      "^12months_disposed_"
    ),
    Category = recode(
      Category,
      "Gadget and lifestyle items" =
        "Gadgets & lifestyle items"
    ),
    # The recoded file stores the six response categories
    # as numeric codes from 1 to 6.
    Band = recode(
      as.character(Code),
      "1" = "0",
      "2" = "1",
      "3" = "2 to 5",
      "4" = "6 to 9",
      "5" = "10 to 19",
      "6" = "20+"
    ),
    Band = factor(
      Band,
      levels = eol_band_levels
    )
  )

disposed_summary <- disposed_long |>
  group_by(Category) |>
  summarise(
    n_eligible = n(),
    n_disposed = sum(Band != "0"),
    pct = weighted_mean_safe(Band != "0", analysis_weight),
    .groups = "drop"
  )

format_disposed_percent <- function(category) {
  format_percent(
    disposed_summary$pct[
      disposed_summary$Category == category
    ]
  )
}

disposed_code_min <- c(
  "1" = 0,
  "2" = 1,
  "3" = 2,
  "4" = 6,
  "5" = 10,
  "6" = 20
)

disposed_code_max <- c(
  "1" = 0,
  "2" = 1,
  "3" = 5,
  "4" = 9,
  "5" = 19,
  "6" = Inf
)

disposed_combined_levels <- c(
  "No item disposed of",
  "Exactly 1 item",
  "Definitely 2 to 5 items",
  "Could be 2 to 5 or 6+ items",
  "Definitely 6 or more items"
)

disposed_combined <- df |>
  transmute(
    analysis_weight,
    across(
      all_of(disposed_non_vape_cols),
      as.character
    )
  ) |>
  filter(
    if_all(
      all_of(disposed_non_vape_cols),
      ~ !is.na(.x)
    )
  ) |>
  mutate(
    total_min = rowSums(
      across(
        all_of(disposed_non_vape_cols),
        \(x) unname(disposed_code_min[x])
      )
    ),
    total_max = rowSums(
      across(
        all_of(disposed_non_vape_cols),
        \(x) unname(disposed_code_max[x])
      )
    ),
    Combined_total = case_when(
      total_max == 0 ~ "No item disposed of",
      total_min == 1 & total_max == 1 ~ "Exactly 1 item",
      total_min >= 2 & total_max <= 5 ~ "Definitely 2 to 5 items",
      total_min > 5 ~ "Definitely 6 or more items",
      TRUE ~ "Could be 2 to 5 or 6+ items"
    ),
    Combined_total = factor(
      Combined_total,
      levels = disposed_combined_levels
    )
  )

disposed_combined_summary <- disposed_combined |>
  group_by(Combined_total, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  arrange(Combined_total)

disposed_combined_pct <- setNames(
  disposed_combined_summary$pct,
  as.character(disposed_combined_summary$Combined_total)
)

pct_any_disposed_non_vape <- 1 -
  disposed_combined_pct[["No item disposed of"]]
pct_exactly_one_disposed_non_vape <- disposed_combined_pct[[
  "Exactly 1 item"
]]
pct_definitely_six_plus_disposed_non_vape <- disposed_combined_pct[[
  "Definitely 6 or more items"
]]
pct_definitely_two_five_disposed_non_vape <- disposed_combined_pct[[
  "Definitely 2 to 5 items"
]]
pct_possible_two_five_disposed_non_vape <-
  pct_definitely_two_five_disposed_non_vape +
  disposed_combined_pct[["Could be 2 to 5 or 6+ items"]]

Q14. Over the last 12 months, how many of the following items have you personally disposed of?

Among respondents who have ever bought fast tech, 68.6% disposed of at least one charging or lighting device during the past year, making this category the most widely disposed of, which is coherent with the quantity owned, purchased, and buying intentions.

Half respondents disposed of at least one high-tech item (47.7%) or gadget and lifestyle item (48.4%). The proportion was lower for e-vapes, at 28.8%.

Show R code
disposed_summary |>
  mutate(
    category_type = if_else(
      Category == "E-vapes",
      "E-vapes",
      "Other categories"
    )
  ) |>
  ggplot(aes(
    x = reorder(Category, pct),
    y = pct,
    fill = category_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.2,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Other categories" = bg_accent,
      "E-vapes" = bg_ink_32
    ),
    guide = "none"
  ) +
  scale_y_continuous(
    labels = percent_format(),
    limits = c(0, NA),
    expand = expansion(mult = c(0, 0.12))
  ) +
  coord_flip() +
  labs(
    x = NULL,
    y = "% disposing of at least one item"
  )
Figure 18: Share of previous buyers who disposed of at least one item during the last 12 months, by category

4.1.1 Distribution of the number of items disposed of

Charging and lighting devices are disposed of more frequently and in larger numbers than the other categories, which, again, is consistent with previous results on buying behaviour, ownership and purchase intentions. For high-tech products and gadgets and lifestyle items, reporting no disposal remains the most frequent individual response.

Show R code
category_order <- c(
  "Charging & lighting devices",
  "Gadgets & lifestyle items",
  "High-tech",
  "E-vapes"
)

disposed_long |>
  group_by(Category, Band, .drop = FALSE) |>
  summarise(n = n(), weighted_n = sum(analysis_weight), .groups = "drop_last") |>
  group_by(Category) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  ungroup() |>
  mutate(
    Category = factor(
      Category,
      levels = category_order
    ),
    band_type = if_else(
      as.character(Band) == "0",
      "No item disposed of",
      "At least one item disposed of"
    )
  ) |>
  ggplot(aes(
    x = Band,
    y = pct,
    fill = band_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(
      label = if_else(
        pct >= 0.02,
        percent(pct, accuracy = 0.1),
        ""
      )
    ),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "No item disposed of" = bg_ink_32,
      "At least one item disposed of" = bg_accent
    ),
    guide = "none"
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.14))
  ) +
  facet_wrap(
    ~Category,
    ncol = 2
  ) +
  labs(
    x = "Number of items disposed of",
    y = "% of previous buyers"
  ) +
  theme(
    axis.text.x = element_text(
      angle = 30,
      hjust = 1
    ),
    panel.spacing.y = grid::unit(32, "pt")
  )
Figure 19: Number of fast tech items disposed of during the last 12 months, by category

4.1.2 Combined quantity across categories (excluding e-vapes)

Across the three non-vape categories, 76.0% of previous buyers disposed of at least one fast tech item during the last 12 months. 16.3% disposed of exactly one item, while at least 17.3% disposed of six or more.

The exact share disposing of two to five items in total lies between 20.6% and 42.4%, depending on the exact counts within each category range.

Note: Combined quantities exclude e-vapes and use previous buyers with valid answers for all three categories. Since Q14 records ranges, combined totals preserve uncertainty rather than imputing exact counts.

Show R code
disposed_combined_summary |>
  mutate(
    total_type = case_when(
      Combined_total == "No item disposed of" ~ "None",
      Combined_total == "Could be 2 to 5 or 6+ items" ~ "Range uncertainty",
      TRUE ~ "Classified total"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Combined_total),
    fill = total_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "None" = bg_ink_32,
      "Range uncertainty" = bg_blue_50,
      "Classified total" = bg_accent
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of previous buyers",
    y = NULL
  )
Figure 20: Combined quantity of fast tech items disposed of during the last 12 months, excluding e-vapes

4.2 Reasons for stopping use

Show R code
stopped_reason_summary <- df |>
  select(analysis_weight, all_of(stopping_reason_cols)) |>
  pivot_longer(
    all_of(stopping_reason_cols),
    names_to = "Reason",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Reason = recode(
      Reason,
      "Other...114" = "Other"
    ),
    selected = is_selected(Value)
  ) |>
  group_by(Reason) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct))

format_stopping_reason_percent <- function(reason) {
  format_percent(
    stopped_reason_summary$pct[
      stopped_reason_summary$Reason == reason
    ]
  )
}

Q15. What are the main reasons why you stopped using your small and inexpensive electronic devices?

Product failure is the main reason for stopping use. More than half of respondents (53.3%) reported that an item broke or became defective, 35.8% said that an item stopped working despite appearing physically intact, and 6.3% reported the item became dangerous, underlying some defect.

A smaller proportion no longer needed the item (18.3%) or considered it outdated or obsolete (13.2%).

Note: Respondents could select up to two reasons.

Show R code
stopped_reason_summary |>
  mutate(
    Reason_plot = str_wrap(Reason, width = 42)
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Reason_plot, pct)
  )) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.15))
  ) +
  labs(
    x = "% of eligible respondents",
    y = NULL
  )
Figure 21: Reasons for stopping use of fast tech items

4.3 Disposal habits

Show R code
disposal_method_summary <- df |>
  select(analysis_weight, all_of(disposal_method_cols)) |>
  pivot_longer(
    all_of(disposal_method_cols),
    names_to = "Method",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Method = recode(
      Method,
      "Other...124" = "Other",
      "I don’t remember...125" =
        "I don’t remember"
    ),
    selected = is_selected(Value)
  ) |>
  group_by(Method) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct))

disposal_method_percent <- setNames(
  disposal_method_summary$pct,
  disposal_method_summary$Method
)

disposal_profile_summary <- disposal_response_data |>
  group_by(Profile) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    Profile = factor(
      Profile,
      levels = disposal_profile_levels
    ),
    pct = weighted_n / sum(weighted_n)
  ) |>
  arrange(Profile)

disposal_profile_pct <- setNames(
  disposal_profile_summary$pct,
  as.character(disposal_profile_summary$Profile)
)

n_disposal_respondents <- nrow(
  disposal_response_data
)

n_single_disposal_method <- sum(
  disposal_response_data$n_selected == 1
)

pct_single_disposal_method <-
  weighted_mean_safe(
    disposal_response_data$n_selected == 1,
    disposal_response_data$analysis_weight
  )

n_multiple_disposal_methods <- sum(
  disposal_response_data$n_selected > 1
)

pct_multiple_disposal_methods <-
  weighted_mean_safe(
    disposal_response_data$n_selected > 1,
    disposal_response_data$analysis_weight
  )

disposal_unique_summary <- disposal_response_data |>
  filter(n_selected == 1) |>
  select(
    analysis_weight,
    all_of(c(
      disposal_recycling_reuse_cols,
      disposal_waste_cols,
      disposal_kept_cols
    ))
  ) |>
  pivot_longer(
    -analysis_weight,
    names_to = "Method",
    values_to = "selected"
  ) |>
  filter(selected) |>
  mutate(
    Method = recode(
      Method,
      "Other...124" = "Other",
      "I don’t remember...125" =
        "I don’t remember"
    )
  ) |>
  group_by(Method) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  arrange(desc(pct))

Q16. Thinking about all the devices you have stopped using, what have you done with them?

Just like casual electronic devices, keeping unused items at home is the most common reported behaviour (29.3% of buyers). 27.4% report bringing devices to a recycling centre or municipal waste facility, and 18.9% report using a store collection point. Reuse options were selected less often: 11.2% gave devices away or donated them and 3.4% sold them.

Inappropriate disposal seem to remain frequent: 22.5% reported throwing an item into general household waste, 20.8% into the plastic waste bin, and 6.5% into a street bin.

Note: the plastic-waste-bin option was not displayed in Switzerland.

Show R code
disposal_method_summary |>
  mutate(
    method_type = case_when(
      Method %in% c(
        "I brought them to a recycling centre / municipal waste facility",
        "I brought them to a recycling point in a store",
        "I gave them away or donated",
        "I sold them"
      ) ~ "Recycling or reuse",

      Method %in% c(
        "I kept them",
        "I don’t remember",
        "Other"
      ) ~ "Kept, other or unknown",

      TRUE ~ "Waste disposal"
    ),
    Method_plot = str_wrap(Method, width = 44)
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Method_plot, pct),
    fill = method_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    name = NULL,
    values = c(
      "Recycling or reuse" = bg_accent,
      "Kept, other or unknown" = bg_ink_32,
      "Waste disposal" = bg_pink
    ),
    guide="none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of buyers",
    y = NULL
  )
Figure 22: What respondents did with fast tech devices they stopped using

4.3.1 Mutually exclusive disposal profiles

If we group the disposal methods, we see that 31.9% reported recycling or reuse methods only, whereas 26.9% reported waste-disposal methods only. A further 15.5% reported only keeping devices, and 25.6% combined methods belonging to more than one group.

Note: “Other” and “I don’t remember” are excluded.

Show R code
disposal_profile_summary |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Profile),
    fill = Profile
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Recycling or reuse only" = bg_accent,
      "Waste disposal only" = bg_pink,
      "Kept only" = bg_ink_32,
      "Mixed methods" = bg_blue
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of previous buyers",
    y = NULL
  )
Figure 23: Mutually exclusive disposal profiles among previous buyers

4.3.2 Disposal profiles by country

Show R code
disposal_profile_country_summary <- disposal_response_data |>
  left_join(
    df |>
      transmute(
        respondent_id = row_number(),
        Country
      ),
    by = "respondent_id"
  ) |>
  mutate(
    Profile = factor(
      Profile,
      levels = disposal_profile_levels
    )
  ) |>
  group_by(
    Country,
    Profile,
    .drop = FALSE
  ) |>
  summarise(
    n = n(),
    weighted_n = sum(country_weight),
    .groups = "drop_last"
  ) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  ungroup()

disposal_profile_country_order <-
  disposal_profile_country_summary |>
  filter(Profile == "Recycling or reuse only") |>
  arrange(pct) |>
  pull(Country)

disposal_profile_country_extremes <-
  disposal_profile_country_summary |>
  filter(
    Profile %in% c(
      "Recycling or reuse only",
      "Waste disposal only"
    )
  ) |>
  group_by(Profile) |>
  summarise(
    highest_country = Country[which.max(pct)],
    highest_pct = max(pct),
    lowest_country = Country[which.min(pct)],
    lowest_pct = min(pct),
    .groups = "drop"
  )

country_recycling_profile_extremes <-
  disposal_profile_country_extremes |>
  filter(Profile == "Recycling or reuse only")

country_bin_profile_high <-
  disposal_profile_country_extremes |>
  filter(Profile == "Waste disposal only")

The distribution between disposal habits differs across countries. Reporting recycling or reuse only ranges from 25.7% in Romania to 47.8% in Switzerland.

Note: Percentages are calculated within each country. “Other” and “I don’t remember” answers are excluded. Respondents selecting identifiable methods from more than one route are classified as using mixed methods.

Show R code
disposal_profile_country_summary |>
  mutate(
    Country = factor(
      Country,
      levels = disposal_profile_country_order
    ),
    Profile_plot = recode(
      as.character(Profile),
      "Waste disposal only" = "Bin disposal only"
    ),
    Profile_plot = factor(
      Profile_plot,
      levels = c(
        "Recycling or reuse only",
        "Mixed methods",
        "Kept only",
        "Bin disposal only"
      )
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = Country,
    fill = Profile_plot
  )) +
  geom_col(
    width = bg_bar_width,
    position = position_stack(reverse = TRUE)
  ) +
  geom_text(
    aes(
      label = if_else(
        pct >= 0.05,
        percent(pct, accuracy = 0.1),
        ""
      )
    ),
    position = position_stack(
      vjust = 0.5,
      reverse = TRUE
    ),
    colour = bg_ink,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    name = NULL,
    values = c(
      "Recycling or reuse only" = bg_accent,
      "Mixed methods" = bg_blue,
      "Kept only" = bg_ink_32,
      "Bin disposal only" = bg_pink
    ),
    drop = FALSE
  ) +
  scale_x_continuous(
    labels = percent_format(),
    breaks = seq(0, 1, by = 0.25),
    expand = expansion(mult = c(0, 0.02))
  ) +
  labs(
    x = "% within each country",
    y = NULL
  ) +
  theme(
    legend.position = "top",
    panel.grid.major.y = element_blank()
  )
Figure 24: Mutually exclusive disposal profiles among previous buyers, by country

4.3.3 Disposal method among single-option respondents

5,779 respondents (66.1%) selected only one disposal option. Within this group, keeping the devices and taking them to a recycling centre or municipal waste facility were the two most frequently reported outcomes.

Note: The percentages below sum to 100%, but apply only to respondents who selected exactly one identifiable option. “Other” and “I don’t remember” are excluded. The analysis excludes 2,993 respondents (33.9%) who reported more than one identifiable disposal method. This share is larger than the “Mixed methods” profile because respondents can select several methods belonging to the same profile, such as two recycling routes.

Show R code
disposal_unique_summary |>
  mutate(
    method_type = case_when(
      Method %in% c(
        "I brought them to a recycling centre / municipal waste facility",
        "I brought them to a recycling point in a store",
        "I gave them away or donated",
        "I sold them"
      ) ~ "Recycling or reuse",
      Method == "I kept them" ~ "Kept",
      TRUE ~ "Waste disposal"
    ),
    Method_plot = str_wrap(Method, width = 44)
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Method_plot, pct),
    fill = method_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Recycling or reuse" = bg_accent,
      "Kept" = bg_ink_32,
      "Waste disposal" = bg_pink
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of single-option respondents",
    y = NULL
  )
Figure 25: Disposal method among respondents selecting exactly one option

4.4 Reasons for choosing disposal solutions

Show R code
disposal_motivation_summary <- df |>
  select(analysis_weight, all_of(disposal_motivation_cols)) |>
  pivot_longer(
    all_of(disposal_motivation_cols),
    names_to = "Motivation",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Motivation = recode(
      Motivation,
      "didn’t know where else to put it" =
        "I didn’t know where else to put it",
      "Other...132" = "Other"
    ),
    selected = is_selected(Value)
  ) |>
  group_by(Motivation) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct))

disposal_motivation_percent <- setNames(
  disposal_motivation_summary$pct,
  disposal_motivation_summary$Motivation
)

disposal_profile_motivation_summary <- df |>
  mutate(
    respondent_id = row_number()
  ) |>
  select(
    respondent_id,
    analysis_weight,
    all_of(disposal_motivation_cols)
  ) |>
  pivot_longer(
    all_of(disposal_motivation_cols),
    names_to = "Motivation",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Motivation = recode(
      Motivation,
      "didn’t know where else to put it" =
        "I didn’t know where else to put it",
      "Other...132" = "Other"
    ),
    selected = is_selected(Value)
  ) |>
  inner_join(
    disposal_response_data |>
      select(
        respondent_id,
        Profile
      ),
    by = "respondent_id"
  ) |>
  group_by(
    Profile,
    Motivation
  ) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    Profile = factor(
      Profile,
      levels = disposal_profile_levels
    ),
    Motivation = factor(
      Motivation,
      levels = rev(
        disposal_motivation_summary$Motivation
      )
    ),
    label_colour = if_else(
      pct >= 0.38,
      bg_white,
      bg_ink
    )
  )

format_profile_motivation_percent <- function(
  profile,
  motivation
) {
  format_percent(
    disposal_profile_motivation_summary$pct[
      disposal_profile_motivation_summary$Profile ==
        profile &
        disposal_profile_motivation_summary$Motivation ==
          motivation
    ]
  )
}

Q17. Why did you choose this or these solutions?

Habit is the leading reported explanation for respondents’ end-of-life choices: 38.6% selected what they usually do with that kind of waste. Environmental protection is the second reason (34.0%), while convenience (33.6%) and proximity (16.1%) are also quite commonly selected.

Show R code
disposal_motivation_summary |>
  mutate(
    Motivation_plot = str_wrap(
      Motivation,
      width = 44
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Motivation_plot, pct)
  )) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of previous buyers",
    y = NULL
  )
Figure 26: Reasons for choosing end-of-life solutions

4.4.1 Disposal motivations by disposal profile

The motivations reported for end-of-life choices vary with the disposal profile. Among respondents reporting recycling or reuse only, environmental protection (52.3%) and habit (51.0%) are the two leading motivations.

For respondents reporting waste disposal only, ease is the leading motivation (36.1%), followed by habit (30.6%).

Interestingly, 20.6% selected environmental protection despite reporting only waste-disposal routes, which may indicate uncertainty or lack of knowledge about appropriate e-waste disposal.

Keeping devices without reporting another identifiable outcome is primarily associated with ease (40.5%), while 16.9% reported not really thinking about their choice.

Note: Percentages are calculated within each mutually exclusive profile based on identifiable outcomes; “Other” and “I don’t remember” do not define a profile. Respondents could select several motivations, so percentages within a profile do not sum to 100%. The associations are descriptive and don’t establish causation.

Show R code
disposal_profile_motivation_summary |>
  ggplot(aes(
    x = Profile,
    y = Motivation,
    fill = pct
  )) +
  geom_tile(
    colour = bg_surface,
    linewidth = 1
  ) +
  geom_text(
    aes(
      label = percent(
        pct,
        accuracy = 0.1
      ),
      colour = label_colour
    ),
    size = bg_size_label / .pt
  ) +
  scale_fill_bg_c(
    palette = "seq",
    name = "% within profile",
    breaks = c(0, 0.25, 0.5),
    limits = c(0, 0.55),
    labels = percent_format()
  ) +
  scale_colour_identity() +
  scale_x_discrete(
    labels = \(x) str_wrap(
      x,
      width = 12
    )
  ) +
  scale_y_discrete(
    labels = \(x) str_wrap(
      x,
      width = 40
    )
  ) +
  labs(
    x = NULL,
    y = NULL
  ) +
  theme(
    axis.text.x = element_text(
      lineheight = 0.9
    ),
    panel.grid = element_blank(),
    legend.position = "top"
  )
Figure 27: Reasons for choosing end-of-life solutions, by disposal profile

5 Non-buyers

Show R code
nonbuyers <- df |>
  filter(Buyer == "Non buyer")

n_nonbuyers <- nrow(nonbuyers)
pct_nonbuyers_unweighted <- n_nonbuyers / nrow(df)
pct_nonbuyers <- weighted_mean_safe(
  df$Buyer == "Non buyer",
  df$analysis_weight
)

Respondents were classified as non-buyers when they answered No, never to Q5 on ever having bought a small and inexpensive electronic device. The achieved sample contains 1,091 non-buyers (10.6% of respondents). After population weighting, they represent 12.6% of the population covered by the study.

5.1 Reasons for never having bought fast tech

Show R code
nonbuyer_reason_cols <- c(
  "I don’t know where to buy them",
  "I don’t need them or I already own similar items",
  "prefer higher-quality, longer-lasting alternatives",
  "Because of their impact on the environment",
  "Because of their social impact",
  "Someone else buys electronic devices at home",
  "Other...36",
  "I don’t know...37"
)

nonbuyer_reason_summary <- nonbuyers |>
  select(analysis_weight, all_of(nonbuyer_reason_cols)) |>
  pivot_longer(
    all_of(nonbuyer_reason_cols),
    names_to = "Reason",
    values_to = "Value"
  ) |>
  filter(!is.na(Value)) |>
  mutate(
    Reason = recode(
      Reason,
      "prefer higher-quality, longer-lasting alternatives" =
        "I prefer higher-quality, longer-lasting alternatives",
      "Other...36" = "Other",
      "I don’t know...37" = "I don’t know"
    ),
    selected = is_selected(Value)
  ) |>
  group_by(Reason) |>
  summarise(
    n = sum(selected),
    denominator = n(),
    pct = weighted_mean_safe(selected, analysis_weight),
    .groups = "drop"
  ) |>
  arrange(desc(pct))

format_nonbuyer_reason_percent <- function(reason) {
  format_percent(
    nonbuyer_reason_summary$pct[
      nonbuyer_reason_summary$Reason == reason
    ]
  )
}

Q6. Which of these describe why you have never bought any small and inexpensive electronic device?

Perceived lack of need or already owning similar products are the main reasons for never purchasing fast tech, selected by almost half of non-buyers.

Preference for higher-quality and longer-lasting alternatives ranks second (26.8%). A further 14.3% were unable to identify a specific reason.

Environmental concerns were selected by 10.6%, whereas social impact concerns were mentioned less frequently (3.1%).

Note: Because respondents could select more than one answer, the percentages do not sum to 100%.

Show R code
nonbuyer_reason_summary |>
  mutate(
    Reason_plot = str_wrap(Reason, width = 44)
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Reason_plot, pct)
  )) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(
    x = "% of non-buyers",
    y = NULL
  )
Figure 28: Reasons for never having bought fast tech

5.2 Exposure to fast tech among non-buyers

Show R code
exposure_levels <- c(
  "Everyday",
  "At least once a week",
  "At least once a month",
  "Few times a year",
  "Less or never"
)

exposure_comparison_summary <- df |>
  filter(
    !is.na(`SeeFast-tech`),
    Buyer %in% c("Buyer", "Non buyer")
  ) |>
  mutate(
    Buyer_group = recode(
      Buyer,
      "Buyer" = "Buyers",
      "Non buyer" = "Non-buyers"
    ),
    Buyer_group = factor(
      Buyer_group,
      levels = c("Non-buyers", "Buyers")
    ),
    Frequency = factor(
      `SeeFast-tech`,
      levels = exposure_levels
    )
  ) |>
  group_by(Buyer_group, Frequency, .drop = FALSE) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop_last"
  ) |>
  group_by(Buyer_group) |>
  mutate(pct = weighted_n / sum(weighted_n)) |>
  ungroup()

# Retains the non-buyer subset used in the accompanying text.
nonbuyer_exposure_summary <- exposure_comparison_summary |>
  filter(Buyer_group == "Non-buyers") |>
  arrange(Frequency)

format_nonbuyer_exposure_percent <- function(frequency) {
  format_percent(
    nonbuyer_exposure_summary$pct[
      nonbuyer_exposure_summary$Frequency == frequency
    ]
  )
}

pct_exposed_weekly_by_group <- exposure_comparison_summary |>
  filter(
    Frequency %in% c(
      "Everyday",
      "At least once a week"
    )
  ) |>
  group_by(Buyer_group) |>
  summarise(
    pct = sum(pct),
    .groups = "drop"
  ) |>
  deframe()

Q7. How often do you come across small and inexpensive electronic devices? (At work, at friends’, in shops, on the web or social media…)

More than half of non-buyers report being very rarely or never exposed to fast tech items (54.7%), which contrasts with 74.4% of buyers reporting being exposed daily or at least once a week.

Note: These measures report buyers and non-buyers perceptions. They can be exposed without noticing or remembering.

Show R code
exposure_comparison_summary |>
  mutate(
    Frequency_plot = factor(
      Frequency,
      levels = rev(exposure_levels)
    )
  ) |>
  ggplot(aes(
    x = Frequency_plot,
    y = pct,
    fill = Buyer_group
  )) +
  geom_col(
    position = position_dodge(width = 0.74),
    width = 0.64
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    position = position_dodge(width = 0.74),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    name = NULL,
    values = c(
      "Buyers" = bg_accent,
      "Non-buyers" = bg_accent_50
    ),
    breaks = c(
      "Buyers",
      "Non-buyers"
    )
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  coord_flip() +
  labs(
    x = NULL,
    y = "% within each group"
  )
Figure 29: Frequency of exposure to fast tech, by purchasing status

6 Perception and Willingness

The forthcoming results describe a certain degree of indifference among an important proportion of the respondents regarding fast tech and its environmental impact, which does not seem to be perceived as a problem.

6.1 Device satisfaction

Show R code
satisfaction_levels <- c(
  "Very dissatisfied",
  "Dissatisfied",
  "Neither satisfied nor dissatisfied",
  "Satisfied",
  "Very satisfied"
)

satisfaction_summary <- summarise_response_distribution(
  df,
  "Satisfaction",
  satisfaction_levels
)

pct_satisfied <- satisfaction_summary |>
  filter(Response %in% c("Satisfied", "Very satisfied")) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

pct_dissatisfied <- satisfaction_summary |>
  filter(Response %in% c("Dissatisfied", "Very dissatisfied")) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

Q18. Overall, thinking back on the small and inexpensive devices you used, you would say you are…

Only 8.4% declared to be unsatisfied of their fast tech devices. There’s actually a strong majority being satisfied (60.9%), while the rest (30.7%) express a neutral opinion.

Note: Question 18 was shown only to respondents who had previously bought fast tech.

Show R code
satisfaction_summary |>
  ggplot(aes(x = Response, y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(x = NULL, y = "% of previous buyers") +
  theme(
    axis.text.x = element_text(angle = 25, hjust = 1)
  )
Figure 30: Overall satisfaction with fast tech devices

6.2 Willingness to pay more

Show R code
pay_more_summary <- summarise_response_distribution(
  df,
  "Pay more",
  willingness_to_pay_levels
)

pct_willing_pay_more <- pay_more_summary |>
  filter(Response != "No") |>
  summarise(pct = sum(pct)) |>
  pull(pct)

Q19. When you bought those small and inexpensive devices, would you have been willing to pay more for similar items that you could use over a longer time period?

Even though most of them report to be satisfied with they fast tech items, a majority of buyers (80.3%) would have been willing to pay more for longer-lasting alternatives. More than half of the buyers are willing to pay more for some items, rather than for most or all purchases.

Show R code
pay_more_summary |>
  mutate(
    response_type = if_else(
      as.character(Response) == "No",
      "No",
      "Other responses"
    )
  ) |>
  ggplot(aes(
    x = Response,
    y = pct,
    fill = response_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Other responses" = bg_accent,
      "No" = bg_ink_32
    ),
    guide = "none"
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(
    x = NULL,
    y = "% of previous buyers"
  ) +
  theme(
    axis.text.x = element_text(
      angle = 25,
      hjust = 1
    )
  )
Figure 31: Willingness to pay more for longer-lasting alternatives

6.3 Willingness to replace

Show R code
replacement_summary <- summarise_response_distribution(
  df,
  "Replace",
  replacement_choice_levels
)

pct_replace_inexpensive <- replacement_summary |>
  filter(Response %in% c(
    "Buy the exact same small and inexpensive model",
    "Buy another small and inexpensive device"
  )) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

Q20. If you had to replace a small and inexpensive electronic device that broke, you would…

If a fast tech device broke, 59.1% of previous buyers would replace it with the same model or another small and inexpensive device. By contrast, 33.2% would move to a more expensive alternative, while 6.5% would not replace the device.

That results echoes with the result on device satisfaction, showing that more than half of the buyers are satisfied with their fast tech devices. Since it brings overall satisfaction, it is logical to be willing to replace one’s fast tech device by another one, if not the same. There are still interrogation as to why most of the respondents would have been willing to pay more to replace some by a more durable device.

Show R code
replacement_summary |>
  mutate(Response_plot = str_wrap(Response, width = 38)) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Response_plot, pct)
  )) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(x = "% of previous buyers", y = NULL)
Figure 32: Intended response if a fast tech device broke

6.4 Lifespan and quality compared to expectations

Show R code
lifespan_expectation_levels <- c(
  "Shorter lifespan",
  "Expected lifespan",
  "Longer lifespan"
)

quality_expectation_levels <- c(
  "Lower quality",
  "Expected quality",
  "Higher quality"
)

lifespan_expectation_summary <- summarise_response_distribution(
  df,
  "Global_Lifespan",
  lifespan_expectation_levels
) |>
  mutate(Measure = "Lifespan")

quality_expectation_data <- df |>
  mutate(
    Global_Quality = recode(
      Global_Quality,
      "Hgher quality" = "Higher quality"
    )
  )

quality_expectation_summary <- summarise_response_distribution(
  quality_expectation_data,
  "Global_Quality",
  quality_expectation_levels
) |>
  mutate(Measure = "Quality")

product_expectation_summary <- bind_rows(
  lifespan_expectation_summary,
  quality_expectation_summary
)

extract_product_expectation_proportion <- function(
  measure,
  response
) {
  product_expectation_summary |>
    filter(
      Measure == measure,
      Response == response
    ) |>
    pull(pct)
}

pct_lifespan_met_or_exceeded <-
  product_expectation_summary |>
  filter(
    Measure == "Lifespan",
    Response %in% c(
      "Expected lifespan",
      "Longer lifespan"
    )
  ) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

pct_quality_met_or_exceeded <-
  product_expectation_summary |>
  filter(
    Measure == "Quality",
    Response %in% c(
      "Expected quality",
      "Higher quality"
    )
  ) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

Q21. Globally, would you say that your small and inexpensive electronic devices…

Q21a. …have a shorter lifespan than you expected, the lifespan you expected, or a longer lifespan than you expected?

Q21b. …are of lower quality than you expected, the quality you expected, or higher quality than you expected?

The results are similar across the two dimensions. Around one quarter report outcomes below their expectations (26.8% for lifespan and 23.5% for quality), whereas around one in ten report outcomes above their expectations (10.5% and 8.0%, respectively).

The interesting result is that a majority of previous buyers consider that fast tech devices meet or exceed their expectations: 73.2% for lifespan and 76.5% for quality.

Show R code
product_expectation_summary |>
  mutate(
    assessment = case_when(
      Response %in% c(
        "Shorter lifespan",
        "Lower quality"
      ) ~ "Below expectations",
      Response %in% c(
        "Expected lifespan",
        "Expected quality"
      ) ~ "As expected",
      TRUE ~ "Above expectations"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Response),
    fill = assessment
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Below expectations" = bg_pink,
      "As expected" = bg_ink_32,
      "Above expectations" = bg_accent
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  facet_wrap(
    ~Measure,
    ncol = 1,
    scales = "free_y"
  ) +
  labs(
    x = "% of previous buyers",
    y = NULL
  ) +
  theme(
    panel.spacing.y = grid::unit(26, "pt")
  )
Figure 33: Perceived lifespan and quality of fast tech relative to expectations

6.5 Lifespan and environmental impact relative to more expensive alternatives

Show R code
environment_comparison_levels <- c(
  "Less harmful",
  "Equally harmful",
  "More harmful"
)

lifespan_comparison_levels <- c(
  "Shorter lifespan",
  "Similar lifespan",
  "Greater lifespan"
)

environment_comparison_summary <- summarise_response_distribution(
  df,
  "Comparison_Environmental impact",
  environment_comparison_levels
) |>
  mutate(Comparison = "Environmental impact")

lifespan_comparison_summary <- summarise_response_distribution(
  df,
  "Comparison_Lifespan",
  lifespan_comparison_levels
) |>
  mutate(Comparison = "Lifespan")

alternative_comparison_summary <- bind_rows(
  environment_comparison_summary,
  lifespan_comparison_summary
)

q22_joint_summary <- df |>
  filter(
    !is.na(`Comparison_Environmental impact`),
    !is.na(Comparison_Lifespan)
  ) |>
  group_by(
    Environmental_impact = `Comparison_Environmental impact`,
    Lifespan = Comparison_Lifespan
  ) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    pct = weighted_n / sum(weighted_n),
    Environmental_impact = factor(
      Environmental_impact,
      levels = environment_comparison_levels
    ),
    Lifespan = factor(
      Lifespan,
      levels = lifespan_comparison_levels
    )
  )

q22_joint_top <- q22_joint_summary |>
  slice_max(pct, n = 1, with_ties = FALSE)

q22_joint_unfavourable_pct <- q22_joint_summary |>
  filter(
    Environmental_impact == "More harmful",
    Lifespan == "Shorter lifespan"
  ) |>
  pull(pct)

extract_alternative_comparison_proportion <- function(
  comparison,
  response
) {
  alternative_comparison_summary |>
    filter(
      Comparison == comparison,
      Response == response
    ) |>
    pull(pct)
}

pct_environment_equal_or_less <-
  extract_alternative_comparison_proportion(
    "Environmental impact",
    "Less harmful"
  ) +
  extract_alternative_comparison_proportion(
    "Environmental impact",
    "Equally harmful"
  )

pct_environment_more_harmful <-
  extract_alternative_comparison_proportion(
    "Environmental impact",
    "More harmful"
  )

pct_lifespan_shorter_alternative <-
  extract_alternative_comparison_proportion(
    "Lifespan",
    "Shorter lifespan"
  )

Q22. Compared to more expensive alternatives, you would say that small and inexpensive electronic devices tend to…

  • Q22a. …be less harmful, equally harmful or more harmful to the environment?
  • Q22b. …have a shorter, similar or greater lifespan?

Most respondents (79.0%) consider fast tech devices equally or less harmful to the environment than more expensive alternatives. Only 21.0% perceive them as more harmful.

By contrast, 45.8% expect fast tech devices to have a shorter lifespan than more expensive alternatives. Respondents therefore appear more conscious of a durability disadvantage than of a greater environmental impact.

Show R code
alternative_comparison_summary |>
  mutate(
    assessment = case_when(
      Response %in% c(
        "More harmful",
        "Shorter lifespan"
      ) ~ "Less favourable",
      Response %in% c(
        "Equally harmful",
        "Similar lifespan"
      ) ~ "Equivalent",
      TRUE ~ "More favourable"
    )
  ) |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Response),
    fill = assessment
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Less favourable" = bg_pink,
      "Equivalent" = bg_ink_32,
      "More favourable" = bg_accent
    ),
    guide = "none"
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  facet_wrap(
    ~Comparison,
    ncol = 1,
    scales = "free_y"
  ) +
  labs(
    x = "% of respondents",
    y = NULL
  ) +
  theme(
    panel.spacing.y = grid::unit(26, "pt")
  )
Figure 34: Perceived environmental impact and lifespan compared with more expensive alternatives

The most frequent joint perception combines equally harmful environmental impact with a similar lifespan (36.0%). Only 16.2% simultaneously perceive fast tech as more harmful and shorter-lived than more expensive alternatives.

Durability and environmental judgements overlap only partially.

Show R code
q22_joint_summary |>
  ggplot(aes(
    x = Lifespan,
    y = Environmental_impact,
    fill = pct
  )) +
  geom_tile(
    colour = bg_surface,
    linewidth = 1
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    colour = bg_ink,
    size = bg_size_label / .pt
  ) +
  scale_fill_bg_c(
    palette = "seq",
    labels = percent_format(),
    name = "% of respondents"
  ) +
  scale_x_discrete(
    labels = \(x) str_wrap(x, width = 18)
  ) +
  scale_y_discrete(
    labels = \(x) str_wrap(x, width = 18)
  ) +
  labs(x = "Perceived lifespan", y = "Perceived environmental impact") +
  theme(
    panel.grid = element_blank(),
    legend.position = "top"
  )
Figure 35: Joint perceptions of environmental impact and lifespan relative to more expensive alternatives
Show R code
q22_joint_summary |>
  mutate(
    Environmental_impact_flow = factor(
      str_replace_all(
        as.character(Environmental_impact),
        " ",
        "\n"
      ),
      levels = str_replace_all(
        environment_comparison_levels,
        " ",
        "\n"
      )
    ),
    Lifespan_flow = factor(
      str_replace_all(
        as.character(Lifespan),
        " ",
        "\n"
      ),
      levels = str_replace_all(
        lifespan_comparison_levels,
        " ",
        "\n"
      )
    )
  ) |>
  ggplot(
  aes(
    axis1 = Environmental_impact_flow,
    axis2 = Lifespan_flow,
    y = weighted_n
  )
  ) +
  ggalluvial::geom_alluvium(
    aes(fill = Environmental_impact_flow),
    width = 0.18,
    alpha = 0.45,
    knot.pos = 0.45
  ) +
  ggalluvial::geom_stratum(
    width = 0.18,
    fill = bg_surface,
    colour = bg_ink_32
  ) +
  ggalluvial::stat_stratum(
    geom = "text",
    aes(label = after_stat(stratum)),
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Less\nharmful" = bg_accent,
      "Equally\nharmful" = bg_ink_32,
      "More\nharmful" = bg_pink
    ),
    guide = "none"
  ) +
  scale_x_discrete(
    limits = c("Environmental impact", "Lifespan"),
    expand = expansion(mult = c(0.16, 0.16))
  ) +
  scale_y_continuous(labels = NULL, breaks = NULL) +
  labs(x = NULL, y = NULL) +
  theme(panel.grid = element_blank())
Figure 36: Flow between perceived environmental impact and lifespan relative to more expensive alternatives

7 Opinions, social norms & intentions

7.1 Attitudes on fast tech

Show R code
attitude_levels <- c(
  "Completely unfavourable",
  "Rather unfavourable",
  "Neither favourable nor unfavourable",
  "Rather favourable",
  "Completely favourable"
)

attitude_summary <- summarise_response_distribution(
  df,
  "Attitude_buying",
  attitude_levels
)

attitude_mean <- weighted_mean_safe(
  df$Attitude_buying_recoded,
  df$analysis_weight
)

pct_attitude_favourable <- weighted_mean_safe(
  df$Attitude_buying_recoded >= 4,
  df$analysis_weight
)

pct_attitude_unfavourable <- weighted_mean_safe(
  df$Attitude_buying_recoded <= 2,
  df$analysis_weight
)

Q23a. Regarding buying small and inexpensive electronic devices, you are…

Attitudes towards buying fast tech are mainly neutral, with an average of 3.22 on a five-point scale. Overall, 36.8% are rather or completely favourable, compared with 17.3% who are rather or completely unfavourable.

Show R code
attitude_summary |>
  ggplot(aes(x = Response, y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(x = NULL, y = "% of respondents") +
  theme(
    axis.text.x = element_text(angle = 25, hjust = 1)
  )
Figure 37: Attitude towards buying fast tech

7.2 Social norms perception

7.2.1 Injunctive norm

Show R code
injunctive_levels <- c(
  "Completely disapprove",
  "Rather disapprove",
  "Neither approve nor disapprove",
  "Rather approve",
  "Completely approve"
)

injunctive_summary <- summarise_response_distribution(
  df,
  "Injunctive norm",
  injunctive_levels
)

pct_norm_approve <- weighted_mean_safe(
  df[["Injunctive norm_recoded"]] >= 4,
  df$analysis_weight
)

pct_norm_disapprove <- weighted_mean_safe(
  df[["Injunctive norm_recoded"]] <= 2,
  df$analysis_weight
)

pct_norm_neutral <- weighted_mean_safe(
  df[["Injunctive norm_recoded"]] == 3,
  df$analysis_weight
)

Q23b. People important to you would…

Key concept
An injunctive norm describes the approval or disapproval that people perceive from others, specifically those whose opinions matter to them.

More than half of the respondents (51.0%) believe that important others would neither approve nor disapprove of buying fast tech. Approval is perceived by 35.3%, more than twice the share perceiving disapproval (13.7%).

We can say that buying fast tech is not perceived as something socially disapproved.

Show R code
injunctive_summary |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Response)
  )) +
  geom_col(
    width = bg_bar_width,
    fill = bg_accent
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  scale_y_discrete(
    labels = \(x) str_wrap(x, width = 34)
  ) +
  labs(
    x = "% of respondents",
    y = NULL
  )
Figure 38: Perceived approval of fast tech purchasing by important others

7.2.2 Dynamic norm

Show R code
dynamic_levels <- c(
  "Far fewer people",
  "Fewer people",
  "The same number",
  "More people",
  "Far more people"
)

dynamic_summary <- summarise_response_distribution(
  df,
  "Dynamic norm",
  dynamic_levels
)

pct_norm_more <- weighted_mean_safe(
  df[["Dynamic norm_recoded"]] >= 1,
  df$analysis_weight
)

pct_norm_fewer <- weighted_mean_safe(
  df[["Dynamic norm_recoded"]] <= -1,
  df$analysis_weight
)

pct_norm_equal <- weighted_mean_safe(
  df[["Dynamic norm_recoded"]] == 0,
  df$analysis_weight
)

Q24. Do you think that more or fewer people buy small and inexpensive electronic devices over time?

Key concept
A dynamic norm describes how people perceive a behaviour to be changing over time. In our case, the evolution of people buying fast tech devices.

Almost half of respondents (46.2%) believe that more or far more people are buying fast tech, while 39.7% perceive no change and 14.1% perceive a decline.

Show R code
dynamic_summary |>
  ggplot(aes(
    x = pct,
    y = fct_rev(Response)
  )) +
  geom_col(
    width = bg_bar_width,
    fill = bg_accent
  ) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  scale_y_discrete(
    labels = \(x) str_wrap(x, width = 34)
  ) +
  labs(
    x = "% of respondents",
    y = NULL
  )
Figure 39: Perceived change in fast tech purchasing over time

7.3 Buying intentions

Show R code
future_intention_summary <- summarise_response_distribution(
  df,
  "12months_Intentionbuy",
  future_purchase_intention_levels
)

pct_intend_more <- future_intention_summary |>
  filter(Response %in% c("Much more", "More")) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

pct_intend_less <- future_intention_summary |>
  filter(Response %in% c(
    "Less", "Much less", "I intend to stop"
  )) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

pct_not_intend_reduce <- future_intention_summary |>
  filter(Response %in% c(
    "The same",
    "More",
    "Much more"
  )) |>
  summarise(pct = sum(pct)) |>
  pull(pct)

Q25. Over the next 12 months, do you intend to buy more, fewer or the same number of small and inexpensive electronic devices?

Most respondents (54.6%) expect to buy the same number of fast tech products during the next 12 months. About a tenth (9.3%) intend to buy more or much more, while 36.1% intend to buy less, much less or stop altogether.

Put differently, 63.9% don’t intend to reduce their fast tech consumption, as they expect to buy the same number, more or much more over the next 12 months.

Show R code
future_intention_summary |>
  mutate(
    response_type = if_else(
      as.character(Response) == "I intend to stop",
      "Stop",
      "Other responses"
    ),
    Response = factor(
      as.character(Response),
      levels = future_purchase_intention_levels
    )
  ) |>
  ggplot(aes(
    x = Response,
    y = pct,
    fill = response_type
  )) +
  geom_col(width = bg_bar_width) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_fill_manual(
    values = c(
      "Other responses" = bg_accent,
      "Stop" = bg_ink_32
    ),
    guide = "none"
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(
    x = NULL,
    y = "% of respondents"
  ) +
  theme(
    axis.text.x = element_text(
      angle = 25,
      hjust = 1
    )
  )
Figure 40: Intended change in fast tech purchases over the next 12 months

7.4 Views on consumption

Show R code
agreement_levels <- c(
  "I completely disagree",
  "I disagree",
  "I neither agree nor disagree",
  "I agree",
  "I completely agree"
)

consumer_view_summary <- summarise_response_distribution(
  df,
  "Consumers should buy fewer",
  agreement_levels
)

pct_consumers_agree <- weighted_mean_safe(
  df[["Consumers should buy fewer_recoded"]] >= 4,
  df$analysis_weight
)

pct_consumers_disagree <- weighted_mean_safe(
  df[["Consumers should buy fewer_recoded"]] <= 2,
  df$analysis_weight
)

Q26a. What do you think about the following statement? “Consumers should buy fewer small and inexpensive electronic devices.”

A short majority of respondents don’t have a strong opinion on the matter, and 40.8% agree or completely agree that consumers should buy fewer devices. Only 16.6% disagree or completely disagree.

Show R code
consumer_view_summary |>
  ggplot(aes(x = Response, y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(x = NULL, y = "% of respondents") +
  theme(
    axis.text.x = element_text(angle = 25, hjust = 1)
  )
Figure 41: Agreement that consumers should buy fewer fast tech devices

7.5 Government regulation over fast tech

Show R code
government_view_summary <- summarise_response_distribution(
  df,
  "Governments should more strictly regulate",
  agreement_levels
)

pct_government_agree <- weighted_mean_safe(
  df[["Governments should more strictly regulate_recoded"]] >= 4,
  df$analysis_weight
)

pct_government_disagree <- weighted_mean_safe(
  df[["Governments should more strictly regulate_recoded"]] <= 2,
  df$analysis_weight
)

Q26b. What do you think about the following statement? “Governments should more strictly regulate the sale of small and inexpensive electronic devices.”

Opinions regarding stricter government regulation are divided. 38.5% agree or completely agree, compared with 25.1% who disagree or completely disagree. The remaining respondents remain neutral.

Show R code
government_view_summary |>
  ggplot(aes(x = Response, y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(x = NULL, y = "% of respondents") +
  theme(
    axis.text.x = element_text(angle = 25, hjust = 1)
  )
Figure 42: Agreement with stricter government regulation of fast tech sales

8 Knowledge & Awareness

8.1 Awareness of platform financial contribution requirements

Show R code
platform_awareness_levels <- c(
  "Yes, I knew this",
  "I heard of it but didn’t know the details",
  "No, I didn’t know this"
)

platform_awareness_summary <- df |>
  filter(!is.na(`Online plateforms obligations`)) |>
  group_by(Response = `Online plateforms obligations`) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    Response = factor(
      Response,
      levels = platform_awareness_levels
    ),
    pct = weighted_n / sum(weighted_n)
  ) |>
  arrange(Response)

Q27. Did you know that online platforms selling electronic devices are legally required to contribute financially to the collection and recycling of electronic waste?

Only 29.1% knew about the requirement, while 13.8% had heard of it without knowing the details. More than half (57.1%) were unaware.

Show R code
platform_awareness_summary |>
  mutate(Response_plot = str_wrap(as.character(Response), 38)) |>
  ggplot(aes(
    x = pct,
    y = fct_reorder(Response_plot, pct)
  )) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    hjust = -0.15,
    size = bg_size_label / .pt
  ) +
  scale_x_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.16))
  ) +
  labs(x = "% of respondents", y = NULL)
Figure 43: Awareness of online platforms’ financial contribution requirements

8.2 Awareness that fast tech contains electronics

Show R code
electronic_awareness_col <- names(df)[
  str_detect(
    names(df),
    "^Before taking this questionnaire, were you aware"
  )
]

electronic_awareness_summary <- df |>
  transmute(
    Response = .data[[electronic_awareness_col]],
    analysis_weight
  ) |>
  filter(!is.na(Response)) |>
  group_by(Response) |>
  summarise(
    n = n(),
    weighted_n = sum(analysis_weight),
    .groups = "drop"
  ) |>
  mutate(
    Response = factor(Response, levels = c("Yes", "No")),
    pct = weighted_n / sum(weighted_n)
  ) |>
  arrange(Response)

Q28. Before taking this questionnaire, were you aware that these small and inexpensive electronic devices contain electronic parts?

Only 17.3% were not aware that fast tech devices contain electronic parts, before completing the questionnaire.

Show R code
electronic_awareness_summary |>
  ggplot(aes(x = Response, y = pct)) +
  geom_col(width = bg_bar_width, fill = bg_accent) +
  geom_text(
    aes(label = percent(pct, accuracy = 0.1)),
    vjust = -0.4,
    size = bg_size_label / .pt
  ) +
  scale_y_continuous(
    labels = percent_format(),
    expand = expansion(mult = c(0, 0.12))
  ) +
  labs(x = NULL, y = "% of respondents")
Figure 44: Awareness that fast tech devices contain electronic parts

Citation

BibTeX citation:
@report{naczaj2026,
  author = {Naczaj, Dimitri and Bonetto, Éric},
  publisher = {Bellegarde Scientific Consulting for the WEEE Forum},
  title = {Fast-Tech {Consumer} {Study}},
  date = {2026},
  langid = {en-GB}
}
For attribution, please cite this work as:
Naczaj, D., & Bonetto, É. (2026). Fast-Tech Consumer Study. Bellegarde Scientific Consulting for the WEEE Forum.