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

为何filter()函数位置不同会生成不同直方图?附对比代码

为什么这两段代码生成的直方图不同?

这是个非常典型的dplyr分组操作误区——核心问题在于**filter(n() >= 100) 在代码中所处的位置,决定了它作用的对象完全不一样**,咱们拆解来看:

第一段代码的执行逻辑

library(tidyverse)
library(dslabs)
movielens %>% 
  group_by(userId) %>% 
  filter(n() >= 100) %>% 
  summarise(mean_rating = mean(rating)) %>% 
  ggplot(aes(mean_rating)) + geom_histogram(bins=30, col="black")
  1. 第一步按userId分组,此时每个组对应一个用户的所有评分记录
  2. filter(n() >= 100) 在这里的n()指的是每个用户的评分条数——这一步直接把那些评分少于100条的用户组全部过滤掉了,只保留至少打了100分的用户数据
  3. 接下来对剩下的每个用户组计算平均评分,最后用这些“活跃用户”的平均评分绘制直方图

第二段代码的执行逻辑

movielens %>% 
  group_by(userId) %>% 
  summarise(mean_rating = mean(rating)) %>% 
  filter(n() >= 100) %>% 
  ggplot(aes(mean_rating)) + geom_histogram(bins=30, col="black")

这里的坑就在filter的位置:

  1. 同样先按userId分组,然后直接对所有用户(不管评分多少)计算了平均评分
  2. 关键!summarise函数默认会在执行后自动取消分组(相当于调用了ungroup()),所以此时整个数据框已经回到了未分组状态,每行对应一个用户的平均评分
  3. 这时调用filter(n() >= 100),这里的n()指的是整个数据框的总行数(也就是用户总数),而movielens的用户数远大于100,所以这个过滤条件等于完全没起作用——最终你是用所有用户的平均评分绘制了直方图

总结

第一段是“先筛选出评分≥100的用户,再统计他们的平均评分分布”;第二段是“先统计所有用户的平均评分,然后做了一个无效过滤,最终统计所有用户的平均评分分布”。两者的数据源不同,直方图自然就不一样了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:17:40