R讲义:描述统计

Author
Affiliation

刘念夏教授, PhD

Published

30 October 2025

1 分析前的环境设置

1.1 下载安装套件包

本章学习者須先下载安装相關套件包,方能正常運行。

#如果之前有下载过,会跳过不下载;如果之前没有下载过,会下载安装套件包
if (!require("showtext")) install.packages("showtext")
if (!require("dplyr")) install.packages("dplyr")
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("ggiraphExtra")) install.packages("ggiraphExtra")
if (!require("sjlabelled")) install.packages("sjlabelled")
if (!require("sjmisc")) install.packages("sjmisc")
if (!require("sjPlot")) install.packages("sjPlot")
if (!require("knitr")) install.packages("knitr")
if (!require("RCPA3")) install.packages("RCPA3")

1.2 环境设置

我们通常会将R的工作环境先进行一些设置,这些设置包括了 “设定当前工作目录”“设定系統中文文字编码”、以及“设定绘图物件中的中文文字”等项。

#设置工作目录
setwd("/Users/simonfair/Desktop/量化研究数据分析/R ch6 描述统计")

#设置系統中文文字编码(简体中文)
Sys.setlocale(category = "LC_ALL", locale = "zh_CN.UTF-8") 
[1] "zh_CN.UTF-8/zh_CN.UTF-8/zh_CN.UTF-8/C/zh_CN.UTF-8/zh_CN.UTF-8"
#使绘图物件中的中文文字能正确呈现
#调用加载"showtext"套件包
library(showtext) 
showtext_auto(enable = TRUE)

2 数据预备

2.1 导入外部数据

导入外部数据,例如:SPSS数据(.sav),stata数据(.dta),CSV数据(.csv),或 Excel数据(.xlsx)等等。 此处我们透过 sjlabelled 套件包的 read_spss( ) 函数, 将外部SPSS数据(TCS2015sc.sav)导入到R,将之储存(save)为R数据档(TCS2015sc.rda)。储存后,使用者可以将其R数据档叫进(load)到R记忆体。

sjlabelled套件包的 read_spss( )函数, 不仅可以将外部SPSS数据导入到R,也可以在导入的过程中,自动将SPSS数据档中的 类别变量,自动转化为 因子变量(factors)。

#导入SPSS数据档(*.sav)
library(sjlabelled)
TCS2015sc <- read_spss("TCS2015sc.sav") 
Converting atomic to factors. Please wait...
#存成R数据档(*.rda)
save(TCS2015sc, file = "TCS2015sc.rda")

#导入R数据档(*.rda)
load("TCS2015sc.rda")  

2.2 挑选分析变量 dplyr::select( )

使用 dplyr 套件包的 select( )函数, 从R数据档(TCS2015sc)中挑选分析时所需要的变量(此处挑选18个变量),并形成新的分析数据档(mydata)。 进一步使用 dim( ) 函数, 查看分析数据档中的变量数目与观察值数目。

library(dplyr)
mydata <- select(TCS2015sc,
  V1.1,
  I3.1, I3.2, I3.3, I3.4,I3.5, I3.6, I3.7,
  I3.8, I3.9, I3.10, I3.11, I3.12, I3.13,I3.14, 
  I3.88,
  G4.2,
  W_Raking)
dim(mydata) #2002行(观察值), 18列(变量)
[1] 2002   18

2.3 查看数据档中各个变量与变量值的标签 sjPlot::view_df( )

使用 sjPlot 套件包的 view_df( )函数及 show.type=T 參數, 可以查看分析数据档中的变量名称(Name)、变量类型(Type)、变量标签(Label)、变量值(Values)以及变量值标签(Value Labels)。

Table 1

library(sjPlot)
view_df(mydata, #数据档名称
        show.type = T) #呈现变量的类型
Table 1: 分析数据档编码表
Data frame: mydata
ID Name Type Label Values Value Labels
1 V1.1 categorical V1.1. 整体而言,你对于你的生活满不满意 1
2
3
4
非常不满意
不满意
满意
非常满意
2 I3.1 categorical I3.1 哪一项是当前最重要的问题?(经济) 1 经济
3 I3.2 categorical I3. 2 哪一项是当前最重要的问题?(两岸关系) 1 两岸关系
4 I3.3 categorical I3. 3 哪一项是当前最重要的问题?(教育) 1 教育
5 I3.4 categorical I3. 4 哪一项是当前最重要的问题?(医疗) 1 医疗
6 I3.5 categorical I3. 5 哪一项是当前最重要的问题?(治安) 1 治安
7 I3.6 categorical I3. 6 哪一项是当前最重要的问题?(环保) 1 环保
8 I3.7 categorical I3. 7 哪一项是当前最重要的问题?(司法) 1 司法
9 I3.8 categorical I3. 8 哪一项是当前最重要的问题?(社会伦理与价值) 1 社会伦理与价值
10 I3.9 categorical I3. 9 哪一项是当前最重要的问题?(地方建设) 1 地方建设
11 I3.10 categorical I3. 10 哪一项是当前最重要的问题?(国家认同) 1 国家认同
12 I3.11 categorical I3. 11 哪一项是当前最重要的问题?(食品安全) 1 食品安全
13 I3.12 categorical I3. 12 哪一项是当前最重要的问题?(薪资所得) 1 薪资所得
14 I3.13 categorical I3. 13 哪一项是当前最重要的问题?(水土保持) 1 水土保持
15 I3.14 categorical I3. 14 哪一项是当前最重要的问题?(政党对立) 1 政党对立
16 I3.88 categorical I3. 88 哪一项是当前最重要的问题?(其他) 1 其他
17 G4.2 numeric G4.2. 请问你一周会使用社交媒体几天? range: 0.5-7.0
18 W_Raking numeric 加权变量权值 range: 0.8-2.3

3 类别单变量的描述统计

3.1 单选题频数分布

可以使用 R 的内建函数:table( ); prop.table( ),或 sjmisc 套件包的 frq( ) 函数,呈现频数分布。

使用 table( ) 函数,可以呈现类别变量(R称为因子变量)每个类别的频数。合并使用 prop.table( ) 以及 table( )函数, 可以呈现类别变量(R称为因子变量)每个类别的比例或百分比。 如 Table 2

使用 sjmisc 套件包的 frq( ) 函数, 可以呈现类别变量(R称为因子变量)的频数分布。搭配參數 weights=数据档加权变量名称 (例如: weights=mydata$W_Raking),可以呈现 加权后 的频数及百分比。

Table 3 (a), Table 3 (b)

Table 2: 频数分布表-使用table
table(mydata$V1.1) #呈现V1.1变量的频数

   1    2    3    4 
  56  429 1420   97 
prop.table(table(mydata$V1.1)) #呈现比例

         1          2          3          4 
0.02797203 0.21428571 0.70929071 0.04845155 
100*prop.table(table(mydata$V1.1)) #呈现百分比

        1         2         3         4 
 2.797203 21.428571 70.929071  4.845155 
#加载sjmisc套件包
library(sjmisc) 

#原始未加权频数分布
#out="v",将频数分布统计结果在Viewer窗口呈现
frq(mydata$V1.1, out = "v") 
#呈现加权后频数分布
frq(mydata$V1.1, 
    weights = mydata$W_Raking, 
    out = "v") #加权变量"W_Raking"
Table 3: 频数分布表-使用sjmisc
(a) 原始未加权
val label frq raw.prc valid.prc cum.prc
1 非常不满意 56 2.80 2.80 2.80
2 不满意 429 21.43 21.43 24.23
3 满意 1420 70.93 70.93 95.15
4 非常满意 97 4.85 4.85 100.00
NA NA 0 0.00 NA NA
total N=2002 · valid N=2002 · x̄=2.78 · σ=0.57
(b) 加权后
val label frq raw.prc valid.prc cum.prc
1 非常不满意 55 2.75 2.75 2.75
2 不满意 420 20.99 20.99 23.74
3 满意 1420 70.96 70.96 94.70
4 非常满意 106 5.30 5.30 100.00
NA NA 0 0.00 NA NA
total N=2001 · valid N=2001 · x̄=2.79 · σ=0.57

3.2 单选题频数分布(升幂/降幂) sjmisc::frq(, sort.frq=c(“asc”)); sjmisc::frq(, sort.frq=c(“desc”))

使用 sjmisc 套件包的 frq( ) 函数, 並搭配 sort.frq=c(“asc”) 參數, 可以将频数分布表依照频数升幂排列。 搭配 sort.frq=c(“desc”) 參數,可以将频数分布表依照频数降幂排列。

Table 4 (a), Table 4 (b)

library(sjmisc)
frq(mydata$V1.1,
    sort.frq = c("asc"),#按照频数升幂
    out = "v",#将频数分布统计结果在Viewer窗口呈现
    weights = mydata$W_Raking) #使用加权变量
library(sjmisc)
frq(mydata$V1.1,
    sort.frq = c("desc"),#按照频数降幂
    out = "v",#将频数分布统计结果在Viewer窗口呈现
    weights = mydata$W_Raking) #使用加权变量
Table 4: 频数分布表(升降幂)
(a) 按照频数升幂排列(加权后)
val label frq raw.prc valid.prc cum.prc
1 非常不满意 55 2.75 2.75 2.75
4 非常满意 106 5.30 5.30 8.05
2 不满意 420 20.99 20.99 29.04
3 满意 1420 70.96 70.96 100.00
NA NA 0 0.00 NA NA
total N=2001 · valid N=2001 · x̄=2.79 · σ=0.57
(b) 按照频数降幂排列(加权后)
val label frq raw.prc valid.prc cum.prc
3 满意 1420 70.96 70.96 70.96
2 不满意 420 20.99 20.99 91.95
4 非常满意 106 5.30 5.30 97.25
1 非常不满意 55 2.75 2.75 100.00
NA NA 0 0.00 NA NA
total N=2001 · valid N=2001 · x̄=2.79 · σ=0.57

3.3 条形图 sjPlot::plot_frq(, type=“bar”)

使用 sjPlot 套件包的 plot_frq( )函数, 並搭配 type=“bar” 參數,可以呈现条形图。搭配參數 weight.by = “数据档加权变量名称” (例如:weight.by = mydata$W_Raking), 可以呈现加权后的条形图。

Figure 1 (a), Figure 1 (b)

#绘制条形图1-原始未加权
library(sjPlot)
plot_frq(mydata$V1.1,#数据档$变量
         type = "bar") #条形图
         
#绘制条形图2-加权后
library(sjPlot)
plot_frq(mydata$V1.1,#数据档$变量
         type = "bar", #条形图
         weight.by = mydata$W_Raking) #加权变量
(a) 原始未加权
(b) 加权后
Figure 1: 条形图-使用sjmisc

3.4 饼图 ggiraphExtra::ggPie( ); pie( )

使用 ggiraphExtra 套件包的 ggPie( ) 函数, 可以产生饼图(原始未加权)。

Figure 2

3.4.1 ggiraphExtra :: ggPie

#加载套件包
library(ggplot2)
library(ggiraphExtra)

#产生饼图1-原始未加权
ggPie(mydata,aes(pies = V1.1))
Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
ℹ Please use tidy evaluation idioms with `aes()`.
ℹ See also `vignette("ggplot2-in-packages")` for more information.
ℹ The deprecated feature was likely used in the ggiraphExtra package.
  Please report the issue to the authors.
Figure 2: 饼图1(使用ggiraphExtra::ggPie)

如果要产生加权后的饼图,则可先使用 sjmisc::frq(, weights=加权变量名称), 产生加权后频数分布表(如 Table 5),然后使用 pie( )函数,搭配相关的參數,就可以产生加权后的饼图(如 Figure 3)。

3.4.2 sjmisc :: frq + pie

3.4.2.1 产生加权后频数分布表

##产生加权后频数分布表
library(sjmisc)
frq(mydata$V1.1, #指明分析变量
    weights = mydata$W_Raking,#指明加权变量
    out="v") #在view窗口呈现
Table 5: 分析变量频数分布表(加权后)
V1.1. 整体而言,你对于你的生活满不满意 (xw) <categorical>
val label frq raw.prc valid.prc cum.prc
1 非常不满意 55 2.75 2.75 2.75
2 不满意 420 20.99 20.99 23.74
3 满意 1420 70.96 70.96 94.70
4 非常满意 106 5.30 5.30 100.00
NA NA 0 0.00 NA NA
total N=2001 · valid N=2001 · x̄=2.79 · σ=0.57

3.4.2.2 依次输入数据(百分比)產生一個向量

#依次输入数据(百分比)產生一個向量,并加以命名
pie.pct <- c(2.75,20.99,70.96,5.30)  

col_c = c(1:4) #使用系统预设的颜色1,颜色2,颜色3,颜色4

3.4.2.3 产生饼图(加權後)

#产生pie图
pie(pie.pct, 
    radius = 1, #设置圆饼图的半径长度
    labels = c("非常不满意 2.75%", "不满意 20.99%", 
               "满意 70.96%", "非常满意 5.30%"), 
    col = col_c) #加上颜色与说明的pie图
Figure 3: 饼图2(使用sjmisc::frq + pie)

3.5 多选题的频数分布

多选题有两种百分比:

  • 一种是以 选项频数/总反应频数 所得到的百分比(percent of responses)

  • 另一种是以选项频数/总样本数所得到的百分比 (percent of cases)

一般是看后者(percent of cases)

多选题的概念,是把每一个 选项 当成一个 题目(变量) 来处理。 以下以 “哪一项是当前最重要的问题” (多选,有15个选项)为例, 说明产生多选题频数分布表的一系列代码。

3.5.1 选择符合多选题的问卷题目,呈现各题目的反应频数,计算总反应频数

寻找数据档的变量标签中有包含 “最重要的问题” 的问卷题目, 呈现多选题各题的加权后频数分布,并计算总反应频数。

#加载套件包
library(sjmisc)

#寻找数据档的变量标签中有包含"最重要的问题"的问卷题目
#结果:I3.1~I3.14, I3.88(共有15个问卷题目)
find_var(mydata, "最重要的问题") 
   col.nr var.name                                         var.label
1       2     I3.1             I3.1 哪一项是当前最重要的问题?(经济)
2       3     I3.2        I3. 2 哪一项是当前最重要的问题?(两岸关系)
3       4     I3.3            I3. 3 哪一项是当前最重要的问题?(教育)
4       5     I3.4           I3. 4 哪一项是当前最重要的问题?(医疗)
5       6     I3.5           I3. 5 哪一项是当前最重要的问题?(治安)
6       7     I3.6           I3. 6 哪一项是当前最重要的问题?(环保)
7       8     I3.7           I3. 7 哪一项是当前最重要的问题?(司法)
8       9     I3.8 I3. 8 哪一项是当前最重要的问题?(社会伦理与价值)
9      10     I3.9       I3. 9 哪一项是当前最重要的问题?(地方建设)
10     11    I3.10      I3. 10 哪一项是当前最重要的问题?(国家认同)
11     12    I3.11      I3. 11 哪一项是当前最重要的问题?(食品安全)
12     13    I3.12      I3. 12 哪一项是当前最重要的问题?(薪资所得)
13     14    I3.13      I3. 13 哪一项是当前最重要的问题?(水土保持)
14     15    I3.14      I3. 14 哪一项是当前最重要的问题?(政党对立)
15     16    I3.88          I3. 88 哪一项是当前最重要的问题?(其他)
#呈现多选题各题的加权后频数分布
library(sjmisc)
frq(mydata, #数据档
    I3.1:I3.14, I3.88, #构成多选题的特定变量
    weights = mydata$W_Raking) #使用加权变量
I3.1 哪一项是当前最重要的问题?(经济) (I3.1) <categorical> 
# total N=1192 valid N=1192 mean=1.00 sd=0.00

Value | Label |    N | Raw % | Valid % | Cum. %
-----------------------------------------------
    1 |  经济 | 1192 |   100 |     100 |    100
 <NA> |  <NA> |    0 |     0 |    <NA> |   <NA>

I3. 2 哪一项是当前最重要的问题?(两岸关系) (I3.2) <categorical> 
# total N=319 valid N=319 mean=1.00 sd=0.00

Value |    Label |   N | Raw % | Valid % | Cum. %
-------------------------------------------------
    1 | 两岸关系 | 319 |   100 |     100 |    100
 <NA> |     <NA> |   0 |     0 |    <NA> |   <NA>

I3. 3 哪一项是当前最重要的问题?(教育) (I3.3) <categorical> 
# total N=650 valid N=650 mean=1.00 sd=0.00

Value | Label |   N | Raw % | Valid % | Cum. %
----------------------------------------------
    1 |  教育 | 650 |   100 |     100 |    100
 <NA> |  <NA> |   0 |     0 |    <NA> |   <NA>

I3. 4 哪一项是当前最重要的问题?(医疗) (I3.4) <categorical> 
# total N=225 valid N=225 mean=1.00 sd=0.00

Value | Label |   N | Raw % | Valid % | Cum. %
----------------------------------------------
    1 |  医疗 | 225 |   100 |     100 |    100
 <NA> |  <NA> |   0 |     0 |    <NA> |   <NA>

I3. 5 哪一项是当前最重要的问题?(治安) (I3.5) <categorical> 
# total N=381 valid N=381 mean=1.00 sd=0.00

Value | Label |   N | Raw % | Valid % | Cum. %
----------------------------------------------
    1 |  治安 | 381 |   100 |     100 |    100
 <NA> |  <NA> |   0 |     0 |    <NA> |   <NA>

I3. 6 哪一项是当前最重要的问题?(环保) (I3.6) <categorical> 
# total N=197 valid N=197 mean=1.00 sd=0.00

Value | Label |   N | Raw % | Valid % | Cum. %
----------------------------------------------
    1 |  环保 | 197 |   100 |     100 |    100
 <NA> |  <NA> |   0 |     0 |    <NA> |   <NA>

I3. 7 哪一项是当前最重要的问题?(司法) (I3.7) <categorical> 
# total N=236 valid N=236 mean=1.00 sd=0.00

Value | Label |   N | Raw % | Valid % | Cum. %
----------------------------------------------
    1 |  司法 | 236 |   100 |     100 |    100
 <NA> |  <NA> |   0 |     0 |    <NA> |   <NA>

I3. 8 哪一项是当前最重要的问题?(社会伦理与价值) (I3.8) <categorical> 
# total N=272 valid N=272 mean=1.00 sd=0.00

Value |          Label |   N | Raw % | Valid % | Cum. %
-------------------------------------------------------
    1 | 社会伦理与价值 | 272 |   100 |     100 |    100
 <NA> |           <NA> |   0 |     0 |    <NA> |   <NA>

I3. 9 哪一项是当前最重要的问题?(地方建设) (I3.9) <categorical> 
# total N=94 valid N=94 mean=1.00 sd=0.00

Value |    Label |  N | Raw % | Valid % | Cum. %
------------------------------------------------
    1 | 地方建设 | 94 |   100 |     100 |    100
 <NA> |     <NA> |  0 |     0 |    <NA> |   <NA>

I3. 10 哪一项是当前最重要的问题?(国家认同) (I3.10) <categorical> 
# total N=168 valid N=168 mean=1.00 sd=0.00

Value |    Label |   N | Raw % | Valid % | Cum. %
-------------------------------------------------
    1 | 国家认同 | 168 |   100 |     100 |    100
 <NA> |     <NA> |   0 |     0 |    <NA> |   <NA>

I3. 11 哪一项是当前最重要的问题?(食品安全) (I3.11) <categorical> 
# total N=891 valid N=891 mean=1.00 sd=0.00

Value |    Label |   N | Raw % | Valid % | Cum. %
-------------------------------------------------
    1 | 食品安全 | 891 |   100 |     100 |    100
 <NA> |     <NA> |   0 |     0 |    <NA> |   <NA>

I3. 12 哪一项是当前最重要的问题?(薪资所得) (I3.12) <categorical> 
# total N=497 valid N=497 mean=1.00 sd=0.00

Value |    Label |   N | Raw % | Valid % | Cum. %
-------------------------------------------------
    1 | 薪资所得 | 497 |   100 |     100 |    100
 <NA> |     <NA> |   0 |     0 |    <NA> |   <NA>

I3. 13 哪一项是当前最重要的问题?(水土保持) (I3.13) <categorical> 
# total N=71 valid N=71 mean=1.00 sd=0.00

Value |    Label |  N | Raw % | Valid % | Cum. %
------------------------------------------------
    1 | 水土保持 | 71 |   100 |     100 |    100
 <NA> |     <NA> |  0 |     0 |    <NA> |   <NA>

I3. 14 哪一项是当前最重要的问题?(政党对立) (I3.14) <categorical> 
# total N=374 valid N=374 mean=1.00 sd=0.00

Value |    Label |   N | Raw % | Valid % | Cum. %
-------------------------------------------------
    1 | 政党对立 | 374 |   100 |     100 |    100
 <NA> |     <NA> |   0 |     0 |    <NA> |   <NA>

I3. 88 哪一项是当前最重要的问题?(其他) (I3.88) <categorical> 
# total N=31 valid N=31 mean=1.00 sd=0.00

Value | Label |  N | Raw % | Valid % | Cum. %
---------------------------------------------
    1 |  其他 | 31 |   100 |     100 |    100
 <NA> |  <NA> |  0 |     0 |    <NA> |   <NA>
#计算总反应频数(responses=5598)
1192 + 319 + 650 + 225 + 381 + 197 + 236 + 272 + 94 + 168 + 891 + 497 + 71 + 374 + 31
[1] 5598
#全部样本数n=2002

3.5.2 制作一个数据框 data.frame( )

建构四个向量,例如:

  • 向量 i=c( ) 包含不同的类别选项,

  • 向量 x1=c( )包含每个类别选项的频数,

  • 向量 r=c( ) 包含每个类别选项所对应的总反应频数,

  • 向量 n=c( ) 每个类别选项所对应的总样本数。

然后用 data.frame( ) 函数, 将这四个向量合并起来,成为一个 数据框(data frame),命名为 df1

Table 6 (a), Table 6 (b)

#向量  i=c( ) 包含不同的类别选项,
df1 <- data.frame(
 i = c("经济","两岸关系","教育","医疗","治安","环保","司法","社会伦理与价值", "地方建设","国家认同","食品安全","薪资所得","水土保持","政党对立","其他"),
 
#向量 x1=c( )包含每个类别选项的频数
#依次输入每个类别选项的频数
x1 = c(1192,319,650,225,381,197,236,272,
      94,168,891,497,71,371,31),

#向量  r=c( ) 包含每个类别选项所对应的总反应频数,
#依次输入每个类别选项所对应的总反应频数
 r = c(5598,5598,5598,5598,5598,5598,5598,5598,
     5598,5598,5598,5598,5598,5598,5598),

#向量  n=c( ) 每个类别选项所对应的总样本数。
#依次输入每个类别选项所对应的总样本数
n = c(2002,2002,2002,2002,2002,2002,2002,2002,
     2002,2002,2002,2002,2002,2002,2002)
)

# html table
library(sjPlot)
tab_df(df1)
#  kable 表格
library(knitr)
kable(df1, 
      col.names = c("选项", "频数", "总反应频数", "总样本数"))
Table 6: 复选题数据框示例1
(a) 原始data.frame
i x1 r n
经济 1192 5598 2002
两岸关系 319 5598 2002
教育 650 5598 2002
医疗 225 5598 2002
治安 381 5598 2002
环保 197 5598 2002
司法 236 5598 2002
社会伦理与价值 272 5598 2002
地方建设 94 5598 2002
国家认同 168 5598 2002
食品安全 891 5598 2002
薪资所得 497 5598 2002
水土保持 71 5598 2002
政党对立 371 5598 2002
其他 31 5598 2002
(b) 标签data.frame
选项 频数 总反应频数 总样本数
经济 1192 5598 2002
两岸关系 319 5598 2002
教育 650 5598 2002
医疗 225 5598 2002
治安 381 5598 2002
环保 197 5598 2002
司法 236 5598 2002
社会伦理与价值 272 5598 2002
地方建设 94 5598 2002
国家认同 168 5598 2002
食品安全 891 5598 2002
薪资所得 497 5598 2002
水土保持 71 5598 2002
政党对立 371 5598 2002
其他 31 5598 2002

3.5.3 产生一个新变量:“选项频数/总反应频数”的百分比

df1 数据框为基础,透过 dplyr 套件包的 mutate( ) 函数, 产生一个新变量(percent.responses)。

就是将每一个类别选项频数(x1)除以加权后总反应频数(r),得到 “选项频数/总反应频数” 的百分比(percent.responses), 并将新的数据框命名为 df2

Table 7 (a), Table 7 (b)

#加载套件包
library(dplyr)
df2 <- mutate(df1, percent.responses = (x1/r)*100)

# html table
library(sjPlot)
tab_df(df2)
#  kable 表格
library(knitr)
kable(df2, 
      col.names = c("选项", "频数", "总反应频数", "总样本数",
                    "百分比(基于总反应频数)"))
Table 7: 复选题数据框示例2
(a) 原始data.frame
i x1 r n percent.responses
经济 1192 5598 2002 21.29
两岸关系 319 5598 2002 5.70
教育 650 5598 2002 11.61
医疗 225 5598 2002 4.02
治安 381 5598 2002 6.81
环保 197 5598 2002 3.52
司法 236 5598 2002 4.22
社会伦理与价值 272 5598 2002 4.86
地方建设 94 5598 2002 1.68
国家认同 168 5598 2002 3.00
食品安全 891 5598 2002 15.92
薪资所得 497 5598 2002 8.88
水土保持 71 5598 2002 1.27
政党对立 371 5598 2002 6.63
其他 31 5598 2002 0.55
(b) 标签data.frame
选项 频数 总反应频数 总样本数 百分比(基于总反应频数)
经济 1192 5598 2002 21.2933190
两岸关系 319 5598 2002 5.6984637
教育 650 5598 2002 11.6112897
医疗 225 5598 2002 4.0192926
治安 381 5598 2002 6.8060021
环保 197 5598 2002 3.5191140
司法 236 5598 2002 4.2157914
社会伦理与价值 272 5598 2002 4.8588782
地方建设 94 5598 2002 1.6791711
国家认同 168 5598 2002 3.0010718
食品安全 891 5598 2002 15.9163987
薪资所得 497 5598 2002 8.8781708
水土保持 71 5598 2002 1.2683101
政党对立 371 5598 2002 6.6273669
其他 31 5598 2002 0.5537692

3.5.4 产生另一个新变量:“选项频数/总样本数”的百分比

df2 数据框为基础,透过 dplyr 套件包的 mutate( ) 函数, 产生另一个新变量(percent.ceses)。

就是将每一个类别选项频数(x1)除以总样本数(n),得到 选项频数/总样本数的百分比 (percent.cases)。 并将新的数据框命名为 df3

Table 8

#产生另一个新变量("percent.cases"),
#将每一个类别选项频数(x1)除以加权后总样本数(n),得到"选项频数/总样本数"的百分比(percent.cases)

# 加载套件包
library(dplyr)
df3 <- mutate(df2, percent.cases = (x1/n)*100)

# kable 表格
library(knitr)
kable(df3, 
      col.names = c("选项", 
                    "频数", 
                    "总反应频数", 
                    "总样本数",
                    "百分比(基于总反应频数)",
                    "百分比(基于总样本数)"))
Table 8: 复选题数据框示例3
选项 频数 总反应频数 总样本数 百分比(基于总反应频数) 百分比(基于总样本数)
经济 1192 5598 2002 21.2933190 59.540459
两岸关系 319 5598 2002 5.6984637 15.934066
教育 650 5598 2002 11.6112897 32.467532
医疗 225 5598 2002 4.0192926 11.238761
治安 381 5598 2002 6.8060021 19.030969
环保 197 5598 2002 3.5191140 9.840160
司法 236 5598 2002 4.2157914 11.788212
社会伦理与价值 272 5598 2002 4.8588782 13.586414
地方建设 94 5598 2002 1.6791711 4.695305
国家认同 168 5598 2002 3.0010718 8.391608
食品安全 891 5598 2002 15.9163987 44.505494
薪资所得 497 5598 2002 8.8781708 24.825175
水土保持 71 5598 2002 1.2683101 3.546454
政党对立 371 5598 2002 6.6273669 18.531468
其他 31 5598 2002 0.5537692 1.548452

此为最后输出结果。

关于多选题,只要关注各选项所对应的 百分比(基于总样本数) 即可。

Table 8 数据显示,经济(59.5%)、食品安全(44.5%)与教育(32.5%) 为某地民众最关心的三大议题。

4 连续变量的描述统计

4.1 频数分布 sjmisc::frq( )

使用 sjmisc 套件包的 frq( ) 函数, 可以呈现数据档中连续变量(例如:G4.2一周会使用社交媒体几天?)的频数分布(原始未加权与加权后)。

Table 9 (a), Table 9 (b)

#加载套件包
library(sjmisc) 

#G4.2 请问你一周会使用社交媒体几天?
frq(mydata$G4.2, out="v") #频数分布(原始未加权)
frq(mydata$G4.2,weights = mydata$W_Raking,out="v")
                        #频数分布(加权后)
Table 9: 频数分布表-使用sjmisc
(a) 原始未加权
val label frq raw.prc valid.prc cum.prc
0.50 23 1.15 1.83 1.83
1.00 50 2.50 3.97 5.79
1.50 12 0.60 0.95 6.75
2.00 56 2.80 4.44 11.19
2.50 8 0.40 0.63 11.83
3.00 47 2.35 3.73 15.56
3.50 11 0.55 0.87 16.43
4.00 16 0.80 1.27 17.70
4.50 4 0.20 0.32 18.02
5.00 46 2.30 3.65 21.67
5.50 4 0.20 0.32 21.98
6.00 13 0.65 1.03 23.02
6.50 5 0.25 0.40 23.41
7.00 965 48.20 76.59 100.00
NA NA 742 37.06 NA NA
total N=2002 · valid N=1260 · x̄=6.02 · σ=1.94
(b) 加权后
val label frq raw.prc valid.prc cum.prc
0.50 23 1.78 1.78 1.78
1.00 47 3.63 3.63 5.41
1.50 12 0.93 0.93 6.34
2.00 56 4.33 4.33 10.67
2.50 8 0.62 0.62 11.29
3.00 45 3.48 3.48 14.77
3.50 11 0.85 0.85 15.62
4.00 16 1.24 1.24 16.86
4.50 3 0.23 0.23 17.09
5.00 46 3.56 3.56 20.65
5.50 5 0.39 0.39 21.04
6.00 12 0.93 0.93 21.96
6.50 5 0.39 0.39 22.35
7.00 1004 77.65 77.65 100.00
NA NA 0 0.00 NA NA
total N=1293 · valid N=1293 · x̄=6.07 · σ=1.91

4.2 众数 RCPA3::wtd.mode( )

使用 RCPA3 套件包的 wtd.mode( )函数, 可以呈现连续变量的众数(原始未加权与加权后)。

#加载套件包
library(RCPA3) 
wtd.mode(x = mydata$G4.2) #众数(原始未加权) #7
[1] 7
wtd.mode(x = mydata$G4.2,
         w = mydata$W_Raking)#众数(加权后) #7
[1] 7

4.3 中位数 RCPA3::wtd.median( ); median( )

使用 RCPA3 套件包的 wtd.median( )函数, 可以呈现连续变量的中位数(原始未加权与加权后)。 亦可使用 median( )函数,呈现原始未加权的中位数。

#加载套件包
library(RCPA3)
wtd.median(x = mydata$G4.2)#中位数(未加权) #7
[1] 7
wtd.median(x = mydata$G4.2,
           w = mydata$W_Raking) #中位数(加权后) #7
[1] 7
median(mydata$G4.2,na.rm = TRUE) #中位数(原始未加权) #排除缺失值 #7
[1] 7

4.4 平均数 RCPA3::wtd.mean( ); mean( )

使用 RCPA3 套件包的 wtd.mean( ) 函数, 可以呈现连续变量的平均数(原始未加权与加权后)。 亦可使用 mean( ) 函数,呈现原始未加权的平均数。

#加载套件包
library(RCPA3)
wtd.mean(x = mydata$G4.2) #平均数(原始未加权) #6.024
[1] 6.024
wtd.mean(x = mydata$G4.2,
         w = mydata$W_Raking)#平均数(加权后) #6.068
[1] 6.068
mean(mydata$G4.2,na.rm = TRUE) #平均数(原始未加权) #排除缺失值 #6.024
[1] 6.024206

4.5 标准差与方差 RCPA3::wtd.sd( );RCPA3::wtd.var( ); sd( ); var( )

使用 RCPA3 套件包的 wtd.sd( )函数, 可以呈现连续变量的标准差(原始未加权与加权后); wtd.var( )函数,则可以呈现连续变量的方差(原始未加权与加权后)。

亦可使用 sd( )函数, 呈现连续变量的标准差(原始未加权); 使用 var( ) 函数得到方差(原始未加权)。

#加载套件包
library(RCPA3)

#标准差
wtd.sd(x = mydata$G4.2) #标准差(原始未加权) #1.944
[1] 1.944
wtd.sd(x = mydata$G4.2,w = mydata$W_Raking) #标准差(加权后) #1.909
[1] 1.909
#方差
wtd.var(x = mydata$G4.2) #方差(原始未加权) #3.781
[1] 3.781
wtd.var(x = mydata$G4.2, w = mydata$W_Raking) #方差(加权后) #3.643
[1] 3.643
#标准差
sd1 <- sd(mydata$G4.2,na.rm = TRUE) #标准差(原始未加权) #排除遗漏值  
sd1  #1.944425
[1] 1.944425
#方差
var1 <- var(mydata$G4.2,na.rm = TRUE) #方差(原始未加权) #排除遗漏值

var1 #3.780788
[1] 3.780788

4.6 四分位距 RCPA3::wtd.quantile( ); IQR( )

使用 RCPA3 套件包的 wtd.quantile( )函数,搭配 q=c(25,50,75) 参数,可以呈现连续变量的第25%, 50%, 75%百分位(原始未加权与加权后),可据此手工计算,得到四分位距(未加权与加权后)。

亦可使用 IQR( )函数直接得到四分距(原始未加权)。

#加载套件包
library(RCPA3)
wtd.quantile(x = mydata$G4.2, q = c(25, 50, 75)) #原始未加权: 25%(7) 50%(7) 75%(7) 
25% 50% 75% 
  7   7   7 
#四分距=7-7=0

library(RCPA3)
wtd.quantile(x = mydata$G4.2, q = c(25, 50, 75), 
             w = mydata$W_Raking) #加权后:25%(7) 50%(7) 75%*7) 
25% 50% 75% 
  7   7   7 
#四分距=7-7=0

#IQR
IQR(mydata$G4.2, na.rm = T) #原始未加权 #排除遗漏值 #IQR=0
[1] 0

4.7 自訂分位数 RCPA3::wtd.quantile(, q=c())

使用 RCPA3 套件包的 wtd.quantile( )函数,搭配 q=c( ) 参数,可以呈现连续变量的任一分位数百分位(原始未加权与加权后)。

#加载套件包
library(RCPA3)

#自訂分位数(原始未加权)
wtd.quantile(x = mydata$G4.2,
    q = c(10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90)
         )
10% 20% 25% 30% 40% 50% 60% 70% 75% 80% 90% 
  2   5   7   7   7   7   7   7   7   7   7 
#自訂分位数(加权后)
library(RCPA3)
wtd.quantile(x = mydata$G4.2, w = mydata$W_Raking,
   q = c(10, 20, 25, 30, 40, 50, 60, 70, 75, 80, 90)
        )
10% 20% 25% 30% 40% 50% 60% 70% 75% 80% 90% 
  2   5   7   7   7   7   7   7   7   7   7 

4.8 偏态与峰态 RCPA3::wtd.skewness(); RCPA3::wtd.kurtosis()

使用 RCPA3 套件包的 wtd.skewness( )函数, 可以呈现连续变量的偏态(原始未加权与加权后)。

使用 RCPA3 套件包的 wtd.kurtosis( )函数, 可以呈现连续变量的峰态(原始未加权与加权后)。

#加载套件包
library(RCPA3)
#偏态
wtd.skewness(x = mydata$G4.2) #原始未加权 # -1.741
[1] -1.741
wtd.skewness(x = mydata$G4.2, w = mydata$W_Raking) #加权后 # -1.713
[1] -1.713
#峰态
wtd.kurtosis(x = mydata$G4.2) #原始未加权 #4.439
[1] 4.439
wtd.kurtosis(x = mydata$G4.2, w = mydata$W_Raking) #加权后 #4.612
[1] 4.612

4.9 直方图 sjPlot::plot_frq(, type=“histogram”);hist()

使用 sjPlot 套件包的 plot_frq( )函数, 搭配参数 type = “histogram” , 可以呈现连续变量的直方图(原始未加权与加权后)。

亦可使用 hist( )函数, 呈现连续变量的直方图(原始未加权)。

Figure 4 (a), Figure 4 (b), Figure 4 (c)

#加载套件包
library(sjPlot)
#直方图
plot_frq(mydata$G4.2, #分析变量
         type = "histogram") #直方图(原始未加权)
plot_frq(mydata$G4.2, #分析变量
         type = "histogram",#直方图
         weight.by = mydata$W_Ralking)  #加权后 

hist(mydata$G4.2)#呈现直方图(原始未加权)
(a) 原始未加权(使用sjPlot::plot_frq)
(b) 加权后(使用sjPlot::plot_frq)
(c) 原始未加权(使用hist)
Figure 4: 直方图

4.10 直方图+正态曲线图+平均数 sjPlot::plot_frq(, type=“histogram”,normal.curve=T, show.mean=T)

使用 sjPlot 套件包的 plot_frq( ) 函数,搭配参数 type = “histogram” , normal.curve = T,show.mean=T, 可以呈现分析变量的直方图、正态曲线与平均数 (原始未加权与加权后)。

Figure 5 (a), Figure 5 (b)

#加载套件包
library(sjPlot)
#直方图+正态曲线图(原始未加权)
plot_frq(mydata$G4.2, #分析变量
         type = "histogram",#呈现直方图
         normal.curve = T, #呈现正态曲线
         show.mean = T) #呈现平均数
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
ℹ The deprecated feature was likely used in the sjPlot package.
  Please report the issue at <https://github.com/strengejacke/sjPlot/issues>.
#直方图+正态曲线图(加权后)
plot_frq(mydata$G4.2, #分析变量
         type = "histogram",#呈现直方图
         normal.curve = T,  #呈现正态曲线
         show.mean = T,#呈现平均数
         weight.by = mydata$W_Raking) #使用加权变量
(a) 原始未加权(使用sjPlot::plot_frq)
(b) 加权后(使用sjPlot::plot_frq)
Figure 5: 直方图+正态曲线+平均数

4.11 连续变量的描述性统计摘要 sjmisc::descr( )

使用 sjmisc 套件包的 descr( )函数, 可以一次呈现连续变量的大部分统计摘要(原始未加权与加权后)。

Table 10

#加载套件包
library(sjmisc)
#描述统计
result<-descr(mydata, G4.2,
      weights = mydata$W_Raking) #加权后

# kable 表格
library(knitr)
kable(result)
Table 10: 连续变量描述统计摘要
var type label n NA.prc mean sd se range iqr skew
G4.2 numeric G4.2. 请问你一周会使用社交媒体几天? 1295 37.06294 6.067563 1.908706 0.0537717 6.5 (0.5-7) 0 -1.74293
rm(list=ls()) #清除记忆体中所有物件与资料

本章小结

本章所使用到的R套件包与函数摘录如下表。

套件包 函数 说明
内建 setwd ( ) 设置当前工作目录
getwd ( ) 显示当前工作目录
install.packages ( ) 安装套件
library ( ) 加载套件
save ( ) 将档案存成R数据资料档格式(*.rda)
load ( ) 载入R数据资料档(*.rda)
head ( ) 呈现数据档前六笔个案观察值
dim ( ) 呈现数据档的观察值数目与变量数目
names ( ) 查看变量名称
data.frame ( ) 将不同的向量组合为一个数据框
View ( ) 查看数据框
table ( ) 呈现频数
prop.table ( ) 呈现比例
pie ( ) 圆饼图
median ( ) 呈现中位数(原始未加权)
mean ( ) 呈现平均数(原始未加权)
sd ( ) 呈现标准差(原始未加权)
var ( ) 呈现方差(原始未加权)
rm (list=ls( )) 去除R当前工作环境中所有的数据与物件
dplyr select ( ) 挑选分析变量
mutate ( ) 产生新变量
ggiraphExtra ggPie ( ) 产生圆饼图
sjlabelled read_spss ( ) 将SPSS格式数据资料档(*.sav)汇入到R
sjmisc frq ( ) 呈现频数分布表(原始未加权)
frq (, weights= ) 呈现加权后频数分布表(加权后)
descr ( ) 呈现连续变量的摘要统计量(原始未加权)
descr (, weights=) 呈现连续变量的摘要统计量(加权后)
sjPlot view_df ( ) 呈现R数据资料的编码簿
plot_frq (, type=“bar”) 产生条形图(原始未加权)
plot_frq (, type=“bar”, weight.by= ) 产生条形图(加权后)
plot_frq(, type=“histogram”) 产生直方图(原始未加权)
plot_frq (, type=“histogram”,weight.by= ) 产生直方图(加权后)
plot_frq (, type=“histogram”,normal.curve=T, show.mean=T ) 产生直方图+正态曲线图+平均数(原始未加权)
plot_frq (, type=“histogram”,normal.curve=T, show.mean=T, weight.by= ) 产生直方图+正态曲线图+平均数(加权后)
knitr kable( ) 产生kable表格(格式较为良好)
RCPA3 wtd.mode ( ) 众数(原始未加权)
wtd.mode (, w= ) 众数(加权后)
wtd.median ( ) 中位数(原始未加权)
wtd.median (, w= ) 中位数(加权后)
wtd.mean ( ) 平均数(原始未加权)
wtd.mean (, w= ) 平均数(加权后)
wtd.sd ( ) 标准差(原始未加权)
wtd.sd (, w= ) 标准差(加权后)
wtd.var ( ) 方差(原始未加权)
wtd.var (, w= ) 方差(加权后)
wtd.quantile ( ) 分位数(原始未加权)
wtd.quantile (, w= ) 分位数(加权后)
wtd.skewness ( ) 偏态(原始未加权)
wtd.skewness (, w= ) 偏态(加权后)
wtd.kurtosis ( ) 峰态(原始未加权)
wtd.kurtosis (, w= ) 峰态(加权后)