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

使用dplyr的slice_max筛选销售额最高的两个国家全部行的问题排查及含NA值场景处理

我来帮你分析下问题所在,以及怎么修正!

原代码的问题

你当前的代码逻辑是按国家分组后,在每个组内筛选s值最大的2行,但s是每个国家的销售额总和,每个组里的所有行s值都完全一致,所以slice_max会返回每个组里的所有行(只要行数≤2),这显然不是你要的——你真正需要的是先找出销售额总和最高的2个国家,再取出这两个国家的全部行数据。

修正方案(无NA的情况)

正确的思路应该分两步:先计算每个国家的销售额总和,选出总和排名前2的国家;再从原数据中筛选这些国家的所有行。用dplyr可以这么写:

library(dplyr)

df1 <- data.frame(
  country = c(1, 1, 2, 2, 3),
  sales = c(1, 1, 1, 2, 3)
)

# 第一步:找出销售额总和前2的国家
top_countries <- df1 %>% 
  group_by(country) %>% 
  summarise(total_sales = sum(sales)) %>% 
  slice_max(total_sales, n = 2) %>% 
  pull(country)  # 提取top2国家的编号

# 第二步:筛选原数据中属于这些国家的所有行
result <- df1 %>% filter(country %in% top_countries)
result

如果你喜欢链式写法,也可以合并成一段,但分两步的逻辑更清晰、可读性更强。

处理包含NA的情况

当sales字段存在NA时,默认的sum(sales)会返回NA,导致对应的国家无法参与排名。这时候需要在求和时加上na.rm = TRUE参数忽略NA值,修改后的代码如下:

df1 <- data.frame(
  country = c(1, 1, 2, 2, 3),
  sales = c(1, 1, NA, 4, 3)
)

top_countries <- df1 %>% 
  group_by(country) %>% 
  summarise(total_sales = sum(sales, na.rm = TRUE)) %>%  # 关键:加入na.rm=TRUE忽略NA
  slice_max(total_sales, n = 2) %>% 
  pull(country)

result <- df1 %>% filter(country %in% top_countries)
result

这里country2的销售额总和会被计算为sum(NA,4, na.rm=TRUE)=4,country3为3,country1为2,所以最终top2国家是country2和3,结果会包含这两个国家的所有行(如果想去掉带NA的行,可以在最后再加filter(!is.na(sales)))。

关键总结

  • 原代码错误的核心是分组后在组内执行slice_max,而你需要的是在全局范围内选出top国家,再筛选对应行
  • 处理NA值时,一定要在sum()中加入na.rm=TRUE,否则会直接影响排名结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:52:39