R讲义:数据档个案的编辑管理

Author
Affiliation

刘念夏教授, PhD

Published

09 October 2025

1 分析前的环境设置

1.1 下载安装套件包

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

#下载安装套件包
#如果之前有下载过,会跳过不下载;如果之前没有下载过,会下载安装套件包
if (!require("showtext")) install.packages("showtext")
载入需要的程序包:showtext
载入需要的程序包:sysfonts
载入需要的程序包:showtextdb
if (!require("dplyr")) install.packages("dplyr")
载入需要的程序包:dplyr

载入程序包:'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
if (!require("sjlabelled")) install.packages("sjlabelled")
载入需要的程序包:sjlabelled

载入程序包:'sjlabelled'
The following object is masked from 'package:dplyr':

    as_label
if (!require("sjmisc")) install.packages("sjmisc")
载入需要的程序包:sjmisc
if (!require("sjPlot")) install.packages("sjPlot")
载入需要的程序包:sjPlot

1.2 环境设置

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

#设置工作目录(此处要改成你自己的工作目录)
setwd("/Users/simonfair/Desktop/量化研究数据分析/R Ch3 数据档个案的编辑管理")

getwd() #查看目前的工作目录
[1] "/Users/simonfair/Desktop/量化研究数据分析/R Ch3 数据档个案的编辑管理"
#设置系統中文文字编码(简体中文)
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 读取SPSS数据档,并存成R数据档

#加载"sjlabelled" 套件包
library(sjlabelled)

#将SPSS数据汇入到R(数据档要放在目前的工作目录下)
TCS2015small <- read_spss("TCS2015small.sav") 
Converting atomic to factors. Please wait...
#看一下数据档中的前6笔数据
head(TCS2015small)
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T111101006  2    1977     38          3     30    7      1      0    3
2 T111101016  2    1968     47          4    180    2      0      5    3
3 T111101039  2    1988     27          2      0    7      2      0    2
4 T111101040  1    1958     57          5    480    5      0     30    3
5 T111101042  2    1958     57          5    120    7      0     10    3
6 T111101047  1    1988     27          2    480    7      0     30    2
#存成R数据檔
save(TCS2015small, file = "TCS2015small.rda")

#把R数据档叫进来
load("TCS2015small.rda")

3 筛选符合特定条件的个案

3.1 方法一 subset( )

可以使用 “subset( )” 函数,进行特定观察值的选择。

#选择符合特定条件的观察值
age_strata.1 <- subset(TCS2015small, age_strata == 1)

#呈现数据档的前6笔资料,全部变量
head(age_strata.1)
            ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
18  T111101160  2    1996     19          1    300    7      5      0    2
57  T112103140  1    1996     19          1     20    7      2      0    3
74  T112204131  1    1996     19          1     60    7      2      0    1
130 T113206217  1    1996     19          1      0    7      2      0    3
133 T121107009  1    1996     19          1    120    7      1      0    3
288 T123379217  2    1996     19          1      0    7      0     30    3

3.2 方法二 dplyr::filter( )

也可以调用 “dplyr” 套件包中的 “filter( )” 函数, 将数据档根据某些标准筛选出来,成为一个次样本。 并可调用 “sjPlot” 套件包中的 “tab_df( )” 函数, 呈现数据档的资料数目与变量数目

#呈现数据档中的各个变量名称
names(TCS2015small)
 [1] "ID"         "A1"         "A2.year"    "A2.age"     "age_strata"
 [6] "G1.1.A"     "G4.2"       "G4.3.1"     "G4.3.2"     "V1.1"      
#加载dplyr套件包
library(dplyr)

#使用dplyr套件包中的filter函数
#选择TCS2015small数据档中的age_strata变量等于1的观察值,将选择后的数据档另外存成一个数据档,并将该数据档的名称设置为"filter"
filter <- filter(TCS2015small, age_strata == 1) 

#呈现数据档的前6笔资料,全部变量
head(filter)
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T111101160  2    1996     19          1    300    7      5      0    2
2 T112103140  1    1996     19          1     20    7      2      0    3
3 T112204131  1    1996     19          1     60    7      2      0    1
4 T113206217  1    1996     19          1      0    7      2      0    3
5 T121107009  1    1996     19          1    120    7      1      0    3
6 T123379217  2    1996     19          1      0    7      0     30    3
#加载sjPlot套件包
library(sjPlot)

#将数据框以表格方式呈现
tab_df(filter)
ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
T111101160 2 1996 19 1 300 7.00 5 0 2
T112103140 1 1996 19 1 20 7.00 2 0 3
T112204131 1 1996 19 1 60 7.00 2 0 1
T113206217 1 1996 19 1 0 7.00 2 0 3
T121107009 1 1996 19 1 120 7.00 1 0 3
T123379217 2 1996 19 1 0 7.00 0 30 3
T124214073 1 1997 18 1 240 7.00 6 59 3
T125115256 1 1996 19 1 150 7.00 1 0 2
T125216048 2 1997 18 1 60 7.00 2 0 3
T132121116 1 1996 19 1 0 7.00 11 0 3
T132121146 1 1996 19 1 0 7.00 11 0 3
T133224167 2 1996 19 1 120 7.00 5 0 3
T211228150 2 1996 19 1 120 7.00 4 0 4
T221131050 2 1996 19 1 0 7.00 3 0 4
T222133035 2 1996 19 1 45 7.00 3 30 4
T223135074 1 1996 19 1 210 7.00 0 30 3
T311240143 1 1997 18 1 0 7.00 1 0 3
T312141161 1 1996 19 1 60 7.00 0 30 4
T312242146 2 1997 18 1 30 7.00 8 0 4
T322246014 2 1997 18 1 0 7.00 1 0 3
T322246021 1 1996 19 1 0 7.00 1 0 3
T322246169 1 1997 18 1 300 7.00 1 0 3
T331147016 2 1997 18 1 120 2.00 2 0 3
T331147197 1 1996 19 1 23 2.00 1 48 3
T332149106 1 1996 19 1 120 1.50 0 10 3
T341252035 1 1997 18 1 0 7.00 0 30 3
T411153063 2 1997 18 1 60 7.00 2 0 3
T412155062 1 1996 19 1 0 7.00 5 0 3
T412256031 1 1996 19 1 0 7.00 9 0 3
T412256104 2 1997 18 1 0 7.00 3 30 3
T422260064 2 1996 19 1 180 4.00 0 10 4
T431161020 2 1996 19 1 0 7.00 2 30 3
T511266016 1 1997 18 1 60 7.00 1 0 3
T511266088 1 1996 19 1 150 7.00 2 0 3
T511266091 1 1996 19 1 240 7.00 2 0 3
T511266232 1 1997 18 1 0 7.00 1 30 3
T522272051 1 1997 18 1 60 7.00 0 40 3
T611177057 1 1997 18 1 0 7.00 0 10 3

4 随机抽取部分样本

4.1 dplyr::sample_frac( ) 选取特定比例

可以使用 “dplyr” 套件包中的 “sample_frac( )” 函数, 随机选取某一特定比例(例如1%)的部分样本。

#加载"dplyr" 套件包
library(dplyr)

#设置抽样乱数起始点
set.seed(11)

#选取一定比例的样本(例如1%)
s1 <- sample_frac(TCS2015small, 0.01, replace = TRUE)

#呈现数据档的前6笔资料,全部变量
head(s1)
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T521270080  2    1957     58          5    120    7      0     30    3
2 T111202190  2    1969     46          4    480    1      0      5    3
3 T211228013  2    1961     54          5    300    7      0     30    3
4 T231137059  2    1974     41          4      0    7      0     20    3
5 T121107153  1    1962     53          5     10    7      1      0    3
6 T322145101  1    1966     49          4    270    7      0     30    2

4.2 dplyr::sample_n( ) 选取固定个案数

可以使用 “dplyr” 套件包中的 “sample_n( )” 函数, 随机选取固定个案数(例如30个)的样本

#加载"dplyr" 套件包
library(dplyr)

#设置抽样乱数起始点
set.seed(17)

#选取固定个案数据的样本(例如30个样本)
s2 <- sample_n(TCS2015small, 30, replace = TRUE)

#呈现数据档的前6笔资料,全部变量
head(s2)
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T611177102  2    1982     33          3     60    7      1      0    3
2 T521169071  1    1988     27          2    540    7      1     30    3
3 T113105182  1    1955     60          6    180    7      0     30    2
4 T131220079  2    1995     20          2      0    7      4      0    3
5 T332250025  2    1985     30          3    390    7      1      0    2
6 T611177081  2    1990     25          2    120    7      0     30    3

4.3 dplyr::slice( ) 选取固定row

可以使用 “dplyr” 套件包中的 “slice( )” 函数, 选取固定row(行数)的样本(例如10-15行)

#加载"dplyr" 套件包
library(dplyr)

#选取固定row(行数)的样本(例如10-15行)
s3 <- slice(TCS2015small, 10:15)

#呈现数据档的前6笔资料,全部变量
head(s3)
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T111101089  1    1935     80          7     NA   NA     NA     NA    3
2 T111101105  1    1964     51          5    300    7      1      0    3
3 T111101109  2    1978     37          3    420    7      5      0    2
4 T111101112  1    1977     38          3     90    7      0     30    3
5 T111101121  1    1952     63          6     NA   NA     NA     NA    2
6 T111101134  1    1944     71          7      0    1      0     10    2

可以从数据档选取前100个观察值,并另存为R数据档(TCS2015sample100)做为后续分析之用。

#加载"dplyr" 套件包
library(dplyr)

#选取前100个观察值
TCS2015sample100 <- slice(TCS2015small, 1:100)

#呈现数据档的观察值与变量数目
dim(TCS2015sample100) #100个观察值 10个变量
[1] 100  10
#存成R数据檔
save(TCS2015sample100, file = "TCS2015sample100.rda")

#把R数据档叫进来
load("TCS2015sample100.rda") 

5 增加新个案

可以使用 “sjmisc” 套件包 “add_case( )” 函数, 增加新的个案,并赋予其在不同变量中的数值; 且可设置新个案所处的位置(在某一个row之前或之后)。

5.1 sjmisc::add_case(,.before) 放在某一行之前

#加载"sjmisc" 套件包
library(sjmisc)

#增加新观察值,此一观察值的A1变量=2, A2.age变量=55, 位置放在原资料档第一行(row)之前
TCS2015sample_addcase <- add_case(TCS2015sample100,A1 = 2, A2.age = 55,.before = 1) 

#呈现前6笔资料,全部变量
head(TCS2015sample_addcase)
            ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
101       <NA>  2      NA     55       <NA>     NA   NA     NA     NA <NA>
1   T111101006  2    1977     38          3     30    7      1      0    3
2   T111101016  2    1968     47          4    180    2      0      5    3
3   T111101039  2    1988     27          2      0    7      2      0    2
4   T111101040  1    1958     57          5    480    5      0     30    3
5   T111101042  2    1958     57          5    120    7      0     10    3

5.2 sjmisc::add_case(,.after)放在某一行之后

#增加新观察值,此一观察值的A1变量= 2, A2.age变量=55, 位置放在原资料档第一行(row)之后
TCS2015sample_addcase <- add_case(TCS2015sample100,A1 = 2, A2.age = 55,.after = 1)

#呈现前6笔资料,全部变量
head(TCS2015sample_addcase)
            ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1   T111101006  2    1977     38          3     30    7      1      0    3
101       <NA>  2      NA     55       <NA>     NA   NA     NA     NA <NA>
2   T111101016  2    1968     47          4    180    2      0      5    3
3   T111101039  2    1988     27          2      0    7      2      0    2
4   T111101040  1    1958     57          5    480    5      0     30    3
5   T111101042  2    1958     57          5    120    7      0     10    3

6 排序

使用 “dplyr” 套件包 “arrange( )” 函数, 将特定变量依其数值由大到小由小到大排序。

6.1 dplyr::arrange(,desc( )) 由大到小排序

#加载"dplyr" 套件包
library(dplyr)

#根据G1.1.A变量(你每天利用电脑上网工作、学习的时间有多久?)"由大到小" 排序,并另存新档
TCS2015sample_sort_desc <- arrange(TCS2015sample100, desc(G1.1.A))

#呈现前6笔资料,全部变量
head(TCS2015sample_sort_desc) 
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T112204111  1    1981     34          3    720    7      2      0    4
2 T111202070  1    1969     46          4    600    7      5      0    3
3 T112103062  1    1988     27          2    600    7      2      0    3
4 T112103182  1    1989     26          2    600    7     10      0    2
5 T112103219  1    1973     42          4    540    7      1     30    2
6 T112204014  1    1985     30          3    540    7      4      0    3

6.2 dplyr::arrange( )由小大到排序

#加载"dplyr" 套件包
library(dplyr)

#根据G4.2变量(请问你一周会使用社交媒体几天?)"由小到大" 排序,并另存新档
TCS2015sample_sort_asc <- arrange(TCS2015sample100,G4.2)

#呈现前6笔资料,全部变量
head(TCS2015sample_sort_asc) 
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T111202125  2    1976     39          3    480  0.5      0      5    3
2 T112103048  2    1967     48          4    360  0.5      1      0    3
3 T112103195  1    1964     51          5    360  0.5      0     10    3
4 T112204146  1    1940     75          7     60  0.5      0     20    3
5 T111101134  1    1944     71          7      0  1.0      0     10    2
6 T111202190  2    1969     46          4    480  1.0      0      5    3

7 合并两个数据档

可以使用 “sjmisc” 套件包 “add_rows( )” 函数, 将具有 "相同变量名称" 但 "不同个案观察值" 的两个数据档,以增加新个案的方式,加以合并(水平合并)。

7.1 水平合并

Figure 1: 水平合并例示
#加载"sjlabelled" 套件包
library(sjlabelled)

#汇入spss数据档TCS2015sample_a
TCS2015sample_a <- read_spss("TCS2015sc_a.sav") 
Converting atomic to factors. Please wait...
#查看数据档TCS2015sample_a的观察值数目与变量数目
dim(TCS2015sample_a) #800个观察值,5個变量
[1] 800   5
#汇入spss数据档TCS2015sample_b
TCS2015sample_b <- read_spss("TCS2015sc_b.sav") 
Converting atomic to factors. Please wait...
#查看数据档TCS2015sample_b的观察值数目与变量数目
dim(TCS2015sample_b)#200个观察值,5個变量
[1] 200   5
#加载sjmisc套件包
library(sjmisc)

#水平合并(两个数据档,相同变量,不同个案观察值)
mydf_add_rows <- add_rows(TCS2015sample_a, TCS2015sample_b)

dim(mydf_add_rows) #1000个观察值(800+200),5 个变量
[1] 1000    5
#查看前6个个案观察值
head(mydf_add_rows)
          ID strata A1 A2.age age_strata
1 T111101006      1  2     38          3
2 T111101016      1  2     47          4
3 T111101039      1  2     27          2
4 T111101040      1  1     57          5
5 T111101042      1  2     57          5
6 T111101047      1  1     27          2

7.2 纵向合并

Figure 2: 纵向合并例示

7.2.1 方法一 sjmisc::replace_columns( )

使用 “sjmisc” 套件包 “replace_columns( )” 函数, 将具有"相同个案观察值""不同变量名称"的两个数据档,以 增加新变量的方式,加以合并(纵向合并)。

#加载"sjlabelled" 套件包
library(sjlabelled)

#汇入spss数据档c
TCS2015sample_c <- read_spss("TCS2015sc_c.sav") 
Converting atomic to factors. Please wait...
dim(TCS2015sample_c) #2002观察值 5个变量
[1] 2002    5
#呈现数据档(TCS2015sample_c)前6笔资料,5个变量
head(TCS2015sample_c) # ID strata A1 A2.age age_strata
          ID strata A1 A2.age age_strata
1 T111101006      1  2     38          3
2 T111101016      1  2     47          4
3 T111101039      1  2     27          2
4 T111101040      1  1     57          5
5 T111101042      1  2     57          5
6 T111101047      1  1     27          2
#汇入spss数据档d
TCS2015sample_d <- read_spss("TCS2015sc_d.sav") 
Converting atomic to factors. Please wait...
dim(TCS2015sample_d)#2002观察值, 6个变量
[1] 2002    6
#呈现数据档前6笔资料,6个变量
head(TCS2015sample_d) # ID V1.1 V1.2 V1.3 V1.4 V1.5
          ID V1.1 V1.2 V1.3 V1.4 V1.5
1 T111101006    3    3    3    3    3
2 T111101016    3    3    3    3    3
3 T111101039    2    2    4    2    2
4 T111101040    3    4    3    3    3
5 T111101042    3    4    4    4    4
6 T111101047    2    3    4    3    3
#TCS2015sample_c 与 TCS2015sample_d 两个数据档,有共同的变量:"ID"

#纵向合并
#加载"sjmisc"套件包
library(sjmisc)

#"replace_columns( )" 函数 根据共同的变量("ID")进行合并,合并后另存新档(mydf_add_col)
mydf_add_col <- replace_columns(TCS2015sample_c,TCS2015sample_d)

dim(mydf_add_col) #2002个观察值,10个变量
[1] 2002   10
#呈现数据档前6笔资料,全部10个变量
head(mydf_add_col)
          ID strata A1 A2.age age_strata V1.1 V1.2 V1.3 V1.4 V1.5
1 T111101006      1  2     38          3    3    3    3    3    3
2 T111101016      1  2     47          4    3    3    3    3    3
3 T111101039      1  2     27          2    2    2    4    2    2
4 T111101040      1  1     57          5    3    4    3    3    3
5 T111101042      1  2     57          5    3    4    4    4    4
6 T111101047      1  1     27          2    2    3    4    3    3
#ID strata A1 A2.age age_strata(TCS2015sample_c)
#V1.1 V1.2 V1.3 V1.4 V1.5(TCS2015sample_d)

7.2.2 方法二 dplyr::left_join( )

使用 “dplyr” 套件包 “left_join( )” 函数, 也可以将具有"相同个案观察值""不同变量名称"的两个数据档,加以纵向合并。

library(dplyr)

mydf_add_join <- left_join(TCS2015sample_c,TCS2015sample_d)
Joining with `by = join_by(ID)`
dim(mydf_add_join) #2002个观察值,10个变量
[1] 2002   10
head(mydf_add_join)
          ID strata A1 A2.age age_strata V1.1 V1.2 V1.3 V1.4 V1.5
1 T111101006      1  2     38          3    3    3    3    3    3
2 T111101016      1  2     47          4    3    3    3    3    3
3 T111101039      1  2     27          2    2    2    4    2    2
4 T111101040      1  1     57          5    3    4    3    3    3
5 T111101042      1  2     57          5    3    4    4    4    4
6 T111101047      1  1     27          2    2    3    4    3    3

8 转置数据档 sjmisc::rotate_df( )

可以使用 “sjmisc” 套件包 “rodata_df( )” 函数, 进行位置转置(transpose),将数据档的行(row)转成列(column), 列(column)转成行(row)。

#加载"sjmisc"套件
library(sjmisc)

#挑选数据档的部分资料(观察值row,1:5 ; 变量columm 1:10),另存新档(x)
x <- TCS2015sample100[1:5, 1:10]
#呈现X数据档
x
          ID A1 A2.year A2.age age_strata G1.1.A G4.2 G4.3.1 G4.3.2 V1.1
1 T111101006  2    1977     38          3     30    7      1      0    3
2 T111101016  2    1968     47          4    180    2      0      5    3
3 T111101039  2    1988     27          2      0    7      2      0    2
4 T111101040  1    1958     57          5    480    5      0     30    3
5 T111101042  2    1958     57          5    120    7      0     10    3
#使用"rotate_df( )"函数, 进行数据档的转置,并另存新档(x2)
library(sjmisc)
x2 <- rotate_df(x)
#呈现X2数据档
x2
                    1          2          3          4          5
ID         T111101006 T111101016 T111101039 T111101040 T111101042
A1                  2          2          2          1          2
A2.year          1977       1968       1988       1958       1958
A2.age             38         47         27         57         57
age_strata          3          4          2          5          5
G1.1.A             30        180          0        480        120
G4.2                7          2          7          5          7
G4.3.1              1          0          2          0          0
G4.3.2              0          5          0         30         10
V1.1                3          3          2          3          3
#去除 R 当前工作环境中所有的数据与物件
rm(list = ls( ))     

本章小结

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

套件包 函数 说明
内建 setwd ( ) 设置当前工作目录
getwd ( ) 显示当前工作目录
install.packages ( ) 安装套件包
library ( ) 加载套件包
save ( ) 将档案存成R数据资料档格式(*.rda)
load ( ) 载入R数据资料档(*.rda)
head ( ) 呈现数据档前六笔个案观察值
dim ( ) 呈现数据档的观察值数目与变量数目
names ( ) 查看变量名称
subset ( ) 根据某些标准筛选出一个次样本
rm (list=ls( )) 去除R当前工作环境中所有的数据与物件
showtext showtext_auto ( ) 使图形能正确呈现中文
dplyr filter ( ) 将数据档根据某些标准筛选出来成为一个次样本
sample_frac ( ) 随机选取某一特定比例的部分样本
sample_n ( ) 随机挑选固定观察值个案的部分样本
slice ( ) 选取固定rows(行数)的样本
arrange(, desc( )) 将特定变量依其数值由大到小排序
arrange ( ) 将特定变量依其数值由小到大排序
left_join ( ) 纵向合并数据档(相同个案,不同变量)
sjlabelled read_spss ( ) 将SPSS格式数据资料档(*.sav)汇入到R
sjmisc add_case( )(,.before) 增加新个案并将个案放置在某个row(行)之前
add_case( )(,.after) 增加新个案并将个案放置在某个row(行)之后
add_rows ( ) 水平合并数据档(不同个案,相同变量)
replace_columns ( ) 纵向合并数据档(相同个案,不同变量)
rotate_df ( ) 将数据档的row(行)与column(列)进行转置
sjPlot tab_df ( ) 将数据框以表格方式呈现