数据形式转换与分析演示(long vs. wide)

Author

Jason

1 📊 模拟 wide 数据(用于建模)

library(tidyverse)
library(gt)

# 构造 wide 格式面板数据(公司 A 与 B)
df_wide <- tribble(
  ~id, ~year, ~revenue, ~net_profit, ~roe, ~debt_ratio,
  "A", 2018, 100, 12, 0.08, 0.55,
  "A", 2019, 120, 14, 0.09, 0.50,
  "A", 2020, 140, 18, 0.11, 0.47,
  "B", 2018, 110, 13, 0.07, 0.60,
  "B", 2019, 130, 16, 0.08, 0.54,
  "B", 2020, 145, 19, 0.09, 0.50
)

df_wide %>%
  gt() 
id year revenue net_profit roe debt_ratio
A 2018 100 12 0.08 0.55
A 2019 120 14 0.09 0.50
A 2020 140 18 0.11 0.47
B 2018 110 13 0.07 0.60
B 2019 130 16 0.08 0.54
B 2020 145 19 0.09 0.50

2 📉 wide数据形式:描述性分析

普通描述性统计

summary(df_wide[, c("revenue", "net_profit", "roe", "debt_ratio")]) 
    revenue        net_profit         roe            debt_ratio    
 Min.   :100.0   Min.   :12.00   Min.   :0.07000   Min.   :0.4700  
 1st Qu.:112.5   1st Qu.:13.25   1st Qu.:0.08000   1st Qu.:0.5000  
 Median :125.0   Median :15.00   Median :0.08500   Median :0.5200  
 Mean   :124.2   Mean   :15.33   Mean   :0.08667   Mean   :0.5267  
 3rd Qu.:137.5   3rd Qu.:17.50   3rd Qu.:0.09000   3rd Qu.:0.5475  
 Max.   :145.0   Max.   :19.00   Max.   :0.11000   Max.   :0.6000  

tips: summary()返回的并不是数据框,所以不适用于gt()输出,也不适用于stargazer输出(不是不可以,需要转换为数据框格式,较为繁琐)。

利用psych包输出描述性统计(仅保留常见统计量)

library(psych)
library(gt)

# 生成描述性统计
desc2_stats <- describe(df_wide[, c("revenue", "net_profit", "roe", "debt_ratio")]) %>%
  rownames_to_column(var = "variable")

# 格式化输出并保留两位小数
desc2_stats %>%
  select(variable, n, mean, sd, median, min, max) %>%
  gt() %>%
  fmt_number(
    columns = c(mean, sd, median, min, max),
    decimals = 2
  )
variable n mean sd median min max
revenue 6 124.17 17.44 125.00 100.00 145.00
net_profit 6 15.33 2.80 15.00 12.00 19.00
roe 6 0.09 0.01 0.08 0.07 0.11
debt_ratio 6 0.53 0.05 0.52 0.47 0.60

3 📉 wide数据形式:回归分析

利用stargazer包输出回归分析结果

library(stargazer) # 输出论文格式的回归分析结果

model <- lm(roe ~ revenue + net_profit + debt_ratio, data = df_wide)

stargazer(model, type = "text")

===============================================
                        Dependent variable:    
                    ---------------------------
                                roe            
-----------------------------------------------
revenue                       -0.0005          
                              (0.001)          
                                               
net_profit                     0.003           
                              (0.008)          
                                               
debt_ratio                    -0.281           
                              (0.099)          
                                               
Constant                       0.250           
                              (0.086)          
                                               
-----------------------------------------------
Observations                     6             
R2                             0.888           
Adjusted R2                    0.719           
Residual Std. Error       0.007 (df = 2)       
F Statistic              5.271 (df = 3; 2)     
===============================================
Note:               *p<0.1; **p<0.05; ***p<0.01

保存结果为word

stargazer(model, type = "html", out = "regression_table.doc") 

4 📉 转换为 long 格式(为ggplot2绘图做准备)

df_long <- df_wide %>%
  pivot_longer(
    cols = c(revenue, net_profit, roe, debt_ratio),
    names_to = "indicator",
    values_to = "value"
  )

# 添加中英文混合标签用于图示
df_long <- df_long %>%
  mutate(
    indicator_label = case_when(
      indicator == "debt_ratio"  ~ "资产负债率(debt ratio)",
      indicator == "net_profit"  ~ "net_profit(净利润)",
      indicator == "revenue"     ~ "revenue(营业收入)",
      indicator == "roe"         ~ "roe(股东回报率)"
    )
  )

df_long %>%
  gt() 
id year indicator value indicator_label
A 2018 revenue 100.00 revenue(营业收入)
A 2018 net_profit 12.00 net_profit(净利润)
A 2018 roe 0.08 roe(股东回报率)
A 2018 debt_ratio 0.55 资产负债率(debt ratio)
A 2019 revenue 120.00 revenue(营业收入)
A 2019 net_profit 14.00 net_profit(净利润)
A 2019 roe 0.09 roe(股东回报率)
A 2019 debt_ratio 0.50 资产负债率(debt ratio)
A 2020 revenue 140.00 revenue(营业收入)
A 2020 net_profit 18.00 net_profit(净利润)
A 2020 roe 0.11 roe(股东回报率)
A 2020 debt_ratio 0.47 资产负债率(debt ratio)
B 2018 revenue 110.00 revenue(营业收入)
B 2018 net_profit 13.00 net_profit(净利润)
B 2018 roe 0.07 roe(股东回报率)
B 2018 debt_ratio 0.60 资产负债率(debt ratio)
B 2019 revenue 130.00 revenue(营业收入)
B 2019 net_profit 16.00 net_profit(净利润)
B 2019 roe 0.08 roe(股东回报率)
B 2019 debt_ratio 0.54 资产负债率(debt ratio)
B 2020 revenue 145.00 revenue(营业收入)
B 2020 net_profit 19.00 net_profit(净利润)
B 2020 roe 0.09 roe(股东回报率)
B 2020 debt_ratio 0.50 资产负债率(debt ratio)

5 📈 long数据形式:ggplot2 可视化 - 公司财务指标趋势图

library(ggplot2)
library(ggsci)
library(showtext)

ggplot(df_long, aes(x = year, y = value, color = id)) +
  geom_line(size = 1.2) +
  geom_point(size = 2.5) +
  facet_wrap(~ indicator_label, scales = "free_y") +  # 每个指标一图
  scale_color_uchicago() +
  scale_x_continuous(breaks = unique(df_long$year)) +
  labs(
    title = "公司 A 与 B 的财务指标表现",
    x = "年份", y = "指标值", color = "公司"
  ) +
  theme_minimal(base_size = 14)


6 📚 小结

  • Wide 格式:用于模型建模(如 描述性统计分析describe(),回归分析lm()
  • Long 格式:适合可视化(如 ggplot2facet_wrap()
  • 数据形式转换((tidyverse)
    • pivot_longer():wide → long
    • pivot_wider():long → wide