You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在dplyr中基于过滤条件而非分组添加求和聚合列?

Great question! It’s totally reasonable to want cleaner, more readable code instead of chaining multiple mutate() calls with repeated sums. Let’s walk through some better alternatives, both within dplyr and beyond.

Clean Up Your Dplyr Code First

The most straightforward improvement is to consolidate all your aggregation logic into a single summarize() call. This makes your intent immediately clear to anyone reading the code:

library(dplyr)

# One-step grouped summary of all required metrics
summary_table <- df1 %>%
  group_by(country) %>%
  summarize(
    named_active = sum(assets[named == TRUE & active == 1]),
    named = sum(assets[named == TRUE]),
    TotalAssets = sum(assets)
  ) %>%
  ungroup()  # Optional, if you don't need to keep the grouping

summary_table
Dplyr’s "Add Count" Equivalent for Sums: add_tally()

If you love the convenience of add_count() but need sums instead of counts, dplyr::add_tally() is exactly what you’re looking for. Use the wt parameter to specify which variable to sum, and by to define your groups:

df1 %>%
  # Add total assets per country
  add_tally(assets, name = "TotalAssets", by = "country") %>%
  # Add total named assets per country
  add_tally(assets[named == TRUE], name = "named", by = "country") %>%
  # Filter to only named + active entries
  filter(named == TRUE, active == 1) %>%
  # Clean up column names and order
  select(country, named_active = assets, named, TotalAssets)

This mirrors the add_count() workflow perfectly, just swapping row counts for sums of your target variable.

Base R Alternative: ave()

If you prefer sticking to base R, the ave() function can handle grouped conditional sums. It’s a bit more verbose, but no extra packages are needed:

# Calculate total assets per country
df1$TotalAssets <- ave(df1$assets, df1$country, FUN = sum)

# Calculate total named assets per country
df1$named <- ave(
  df1$assets, 
  df1$country, 
  FUN = function(x) sum(x[df1$named[seq_along(x)] == TRUE])
)

# Calculate named + active assets per country
df1$named_active <- ave(
  df1$assets, 
  df1$country, 
  FUN = function(x) sum(x[df1$named[seq_along(x)] == TRUE & df1$active[seq_along(x)] == 1])
)

# Filter and clean up the result
result <- df1[df1$named == TRUE & df1$active == 1, c("country", "named_active", "named", "TotalAssets")]
row.names(result) <- NULL  # Reset row names for cleanliness
result
Even Tighter with data.table

For large datasets or a more compact syntax, data.table offers an extremely clean way to do grouped conditional sums:

library(data.table)

# Convert to data.table format
setDT(df1)

# Group and compute all metrics in one call
result <- df1[, .(
  named_active = sum(assets[named == TRUE & active == 1]),
  named = sum(assets[named == TRUE]),
  TotalAssets = sum(assets)
), by = country]

result

内容的提问来源于stack exchange,提问作者dad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:17:53