基于Lahman数据集,用R语言卡方检验分析球员薪资与联赛相关性的方法是否合理?
联赛与薪资差异分析的方法修正探讨
Hey there! Let's break down your analysis and fix the approach to properly answer your question about salary differences between AL and NL leagues.
核心问题:卡方检验的误用
你当前用chisq.test()的思路存在关键偏差:卡方检验是用来分析两个分类变量的关联,但salary是连续数值变量。当你把它塞进table()里,R会把每个独一无二的薪资值当成独立分类——这会生成一个超级庞大的列联表(你的结果里df=2139,意味着有2140个薪资类别),完全违背了卡方检验的适用场景:
- 卡方检验要求绝大多数单元格的期望频数≥5,而你的列联表中几乎所有薪资对应的频数都极低,导致检验结果不可靠;
- 这种做法只能检验「具体薪资值的出现频率是否和联赛相关」,根本没法直接回答你真正关心的「两个联赛的薪资水平是否有差异」。
适合你的正确分析方法
既然要比较两个联赛的薪资差异,我们需要针对连续因变量+分类自变量的统计方法,这里有几个靠谱的选择:
1. 非参数检验:Mann-Whitney U检验(优先推荐)
薪资数据通常是右偏分布(正如你观察到的长尾),不满足t检验的正态性假设,非参数检验更合适。它用来判断两组数据的分布是否存在显著差异。
修改后的代码示例:
library(tidyverse) library(Lahman) # 用管道式写法合并数据,更清晰 bat_salaries <- Batting %>% left_join(Salaries, suffix = c(".x", ".y")) %>% left_join(Teams, by = c("yearID", "teamID", "lgID"), suffix = c("_individual", "_team")) %>% filter(salary > 0) # 过滤无薪资记录 # 用分位数动态计算截断值(替代硬编码的2350000,代码更可重复) iqr_cutoff <- quantile(bat_salaries$salary, 0.75, na.rm = TRUE) bat_salaries_iqr3 <- bat_salaries %>% filter(salary < iqr_cutoff) # 执行Mann-Whitney检验 wilcox_result <- wilcox.test(salary ~ lgID, data = bat_salaries_iqr3) print(wilcox_result)
2. 参数检验:独立样本t检验(需满足假设)
如果通过对数转换或截断极端值后,薪资数据接近正态分布,也可以用t检验:
# 先可视化检查正态性 bat_salaries_iqr3 %>% ggplot(aes(x = salary)) + geom_histogram(bins = 30) + facet_wrap(~lgID) # 执行t检验 t_test_result <- t.test(salary ~ lgID, data = bat_salaries_iqr3) print(t_test_result)
3. 可视化辅助:箱线图
不管用哪种检验,先做个箱线图直观感受两组薪资的分布差异:
bat_salaries_iqr3 %>% ggplot(aes(x = lgID, y = salary)) + geom_boxplot(fill = "#4292c6", alpha = 0.7) + labs(title = "Salary Distribution by League", x = "League", y = "Annual Salary")
额外小提示
- 你之前手动生成
leagID的步骤完全没必要,直接用原数据的lgID作为分组变量更清晰; - 合并数据时建议加上
na.omit()或明确处理缺失值,避免后续分析出问题; - 截断极端值的做法要谨慎,若为了排除异常值,更推荐用IQR的1.5倍规则(
Q3 + 1.5*IQR),而非只保留到第三四分位数,这样保留的数据更合理。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

