使用dplyr按年份计算指定比率均值/中位数的问题排查
解决dplyr计算年份比率均值/中位数异常的问题
咱先理清楚你遇到的核心问题:计算aqc/(ppent - lag(ppent))的年度均值时结果异常,中位数全为0,大概率是代码逻辑漏了关键步骤,或是没处理数据里的异常情况。下面一步步给你解决:
第一步:先排掉最容易踩的坑——滞后操作没按公司分组
这是用dplyr做时间序列计算最常犯的错!如果直接对整个数据集用lag(ppent),会把不同公司的固定资产数据混在一起滞后,算出来的分母完全不对,结果自然异常。正确的做法是先按公司(gvkey)分组,再计算每个公司自身的年度ppent变化。
第二步:完整的修正代码
我给你写了一套严谨的代码,每一步都加了注释,直接套用到你的数据集上就行:
library(dplyr) # 假设你的数据集名叫df,替换成你实际的数据集名称 result_df <- df %>% # 先按公司+年份排序,确保时间顺序正确,滞后操作才靠谱 arrange(gvkey, fyear) %>% # 按公司分组,计算每个公司的年度固定资产变化 group_by(gvkey) %>% mutate( # 计算ppent的年度变化量 ppent_change = ppent - lag(ppent), # 计算目标比率,同时处理异常情况:分母为0/缺失时设为NA,避免出现Inf/NaN aqc_ratio = ifelse(ppent_change == 0 | is.na(ppent_change), NA, aqc / ppent_change) ) %>% ungroup() %>% # 现在按年份分组,计算均值和中位数,记得排除NA值 group_by(fyear) %>% summarise( mean_aqc_ratio = mean(aqc_ratio, na.rm = TRUE), median_aqc_ratio = median(aqc_ratio, na.rm = TRUE) ) %>% ungroup()
第三步:关键细节解释
- 排序+分组滞后:必须先按
gvkey和fyear排序,再按gvkey分组做滞后,这样每个公司的ppent变化都是自身年度的对比,不会串到其他公司。 - 处理分母异常:当公司当年固定资产没变化(
ppent_change=0)或者是第一年没有上一年数据(lag(ppent)为NA)时,把比率设为NA,这些无意义的数值会严重干扰均值和中位数的计算。 - na.rm=TRUE:计算均值和中位数时一定要加这个参数,不然只要有NA,结果就会变成NA,或者异常值会拉偏结果。
第四步:如果中位数还是0?那得检查数据本身
要是跑了上面的代码,中位数还是全0,大概率是你的业务数据特性导致的:
- 很多公司当年没有并购支出(
aqc=0),这时候比率自然是0,如果这类样本占比极高,中位数就会是0,这是正常的业务现象,不是代码错了。 - 你可以先看看数据分布:
# 查看aqc的数值分布 summary(df$aqc) # 查看计算后的比率分布 result_df_check <- df %>% arrange(gvkey, fyear) %>% group_by(gvkey) %>% mutate(ppent_change = ppent - lag(ppent), aqc_ratio = ifelse(ppent_change == 0 | is.na(ppent_change), NA, aqc / ppent_change)) %>% ungroup() ggplot(result_df_check, aes(x=aqc_ratio)) + geom_histogram(bins=30) - 如果确实是因为大量
aqc=0导致的,你可以选择过滤掉这些样本再计算:# 过滤掉aqc=0的观测值 result_df_filtered <- df %>% filter(aqc != 0) %>% arrange(gvkey, fyear) %>% group_by(gvkey) %>% mutate( ppent_change = ppent - lag(ppent), aqc_ratio = ifelse(ppent_change == 0 | is.na(ppent_change), NA, aqc / ppent_change) ) %>% ungroup() %>% group_by(fyear) %>% summarise( mean_aqc_ratio = mean(aqc_ratio, na.rm = TRUE), median_aqc_ratio = median(aqc_ratio, na.rm = TRUE) ) %>% ungroup()
第五步:验证结果的正确性
你可以抽一两个公司的数据手动计算,对比代码输出的结果,确保逻辑是对的:
# 随便选一个公司的样本数据 sample_company <- df %>% filter(gvkey == "你的某个gvkey值") %>% arrange(fyear) # 手动计算ppent_change和aqc_ratio,和代码结果对比
内容的提问来源于stack exchange,提问作者Ayoze Alfageme
相关产品推荐
相关产品推荐

