[关闭]
@fanxy 2021-09-15T12:17:21.000000Z 字数 9132 阅读 9014

第二讲 数据获取与处理

樊潇彦 复旦大学经济学院 金融数据


0. 准备工作

数据下载:Ch02.rar

  1. setwd("D:\\...\\Ch02")
  2. ## tidyverse 包是一个综合包,内含数据读取与处理(readr,tidyr,dplyr)、作图(ggplot2)、特定数据类型处理(tibble,stringr,forcats),以及函数化编程(purrr)等常用包。
  3. install.packages("tidyverse")
  4. install.packages(c("readstata13","haven","readxl")) # 读写 stata、excel 等其他格式的数据
  5. install.packages(c("babynames","hflights")) # 含姓名和航班数据样本的包
  6. ## 调用
  7. library(tidyverse)
  8. library(readstata13)
  9. library(haven)
  10. library(readxl)
  11. library(babynames)
  12. library(hflights)

1. 数据处理基本概念

1.1 什么是数据?

Wiki: Data are values of qualitative or quantitative variables, belonging to a set of items.

1.2 数据处理主要步骤

  1. 采集:根据研究需要搜集原始数据(raw data)
  2. 读写:读入不同格式的原始数据,存为可以用R进行处理的格式
  3. 整理:通过合并、转换、规约等步骤,得到用于后续研究的整洁数据(tidy data)
    • 数据集成:将多个数据源合并存放在一个一致的数据存储(如数据仓库)中的过程。
    • 数据转换:对数据进行规范化的操作,将数据转换成“适当的”类型和结构。
    • 数据规约:将海量数据进行规约,规约之后的数据仍接近于保持原数据的完整性,但数据量小得多。
  4. 探索:了解数据集的基本情况、数据质量和统计特征,并进行预处理
    • 基本情况:数据维度(样本量、指标数)和频率、指标属性、指标关系等。
    • 数据清洗:查看和处理缺失值、异常值,删除无关数据、重复数据、不一致数据,平滑噪声数据等。
    • 统计分析:计算数据指标的分布、均值、标准差等统计特征,给出统计描述或可视化报告。

2. 数据读写

2.1 读写多种格式文件(.Rdata.csv.txt.xlsx.dta等)。

  1. # 存放和读取.Rdata
  2. library(quantmod)
  3. getSymbols("^GSPC",from="2015-1-1")
  4. tail(GSPC)
  5. save(GSPC,file="GSPC.Rdata") # 将保存历史记录的数据框直接写入本地Rdata文件
  6. rm(GSPC) # 删除变量GSPC之后,内存中无内容,无法访问
  7. load("GSPC.RDATA") # 装载save()函数保存的数据
  8. tail(GSPC)
  9. # .csv文件
  10. class(GSPC) # 原数据为时序类型
  11. GSPC_df=data.frame(Date=as.Date(index(GSPC)), # 日期
  12. coredata(GSPC)) # 数据
  13. class(GSPC_df) # 类型变为 data.frame
  14. str(GSPC_df) # 查看数据结构
  15. write.csv(GSPC,file="GSPC_csv.csv", row.names=F) # 将数据写入.csv文件,row.names=F不会保留行号
  16. GSPC <- read.csv("GSPC_csv.csv",header=T,skip=0) # read.csv为系统自带命令;含表头,即第一行为变量名
  17. class(GSPC) # data.frame类型,但没有日期
  18. # .txt文件
  19. write.table(GSPC_df, "GSPC_txt.txt") # 将.csv数据写为.txt格式
  20. GSPC <- read.table("GSPC_txt.txt",header = T, # read.table为系统自带命令
  21. stringsAsFactors =F) # 字符不要转成因子,第一列 Date 作为字符处理
  22. str(GSPC)
  23. # .dta文件
  24. library(readstata13)
  25. save.dta13(GSPC_df,"GSPC.dta",version=14)
  26. GSPC_dta=read.dta13("GSPC.dta")
  27. str(GSPC_dta)
  28. library(haven)
  29. GSPC=GSPC_df
  30. colnames(GSPC)=gsub("GSPC.","",colnames(GSPC)) # 原变量名中含有"GSPC.",去掉后保存,否则报错
  31. write_dta(GSPC, "GSPC.dta", version=14)
  32. GSPC_dta=read_dta("GSPC.dta")
  33. str(GSPC_dta)
  34. # .xls 或 .xlsx文件
  35. library(readxl)
  36. loan=read_excel("loan.xls")
  37. str(loan) # 发现部分变量名有误,在练习 loan 中介绍如何处理

2.2 用 readr 包读写和处理

1. read_*, write_*:读写不同格式数据文件

  1. library(readr)
  2. library(readxl)
  3. # 以 ',' 为分割符的 .csv 文件
  4. read_csv(system.file("extdata/mtcars.csv", package = "readr"))
  5. read_csv(system.file("extdata/mtcars.csv.zip", package = "readr"))
  6. read_csv(system.file("extdata/mtcars.csv.bz2", package = "readr"))
  7. read_csv("https://github.com/hadley/readr/raw/master/inst/extdata/mtcars.csv")
  8. read_csv("x,y\n1,2\n3,4")
  9. # 其他常用分隔符
  10. data=c("a;b\tc d|e\nf;g\th|i j")
  11. read_csv2(data, col_names=F) # ;
  12. read_tsv(data, col_names=F) # \t
  13. read_table(data, col_names=F) # " "
  14. read_lines(data) # \n
  15. read_delim(data, delim = "|", col_names=F) # 通用,如"|"
  16. # 读入列为固定长度的文件
  17. read_fwf(data, fwf_empty(data)) # 空格分割
  18. read_fwf(data, fwf_widths(c(2, 7))) # 规定每一列字符数
  19. read_fwf(data, fwf_positions(c(1,3), c(2,8))) # 规定起止字符位置
  20. # 作为字符读入
  21. read_file(data)
  22. # 读入log文件
  23. read_log(system.file("extdata/example.log", package = "readr"))
  24. # 将系统自带的 iris 数据存为.csv, .txt等
  25. write_csv(iris, "iris.csv") # ,
  26. write_tsv(iris, "iris.txt") # \t
  27. write_delim(iris, "iris.csv", delim=",") # delim 可以设不同分割符

2. cols: 设置列向量的类型

  1. # 读入数据,最后一列为 character
  2. iris=read_csv("iris.csv")
  3. str(iris)
  4. # 改为 factor
  5. iris=read_csv("iris.csv", col_types = cols(
  6. Species = col_factor(c("setosa", "versicolor", "virginica"))
  7. ))
  8. str(iris)
  9. # 只读入一列 cols_only
  10. iris=read_csv("iris.csv", col_types = cols_only(
  11. Species = col_factor(c("setosa", "versicolor", "virginica"))
  12. ))
  13. head(iris)
  14. # type_convert:直接转换为最有可能的格式
  15. df <- data.frame(
  16. x = as.character(runif(10)),
  17. y = as.character(sample(10)),
  18. stringsAsFactors = FALSE
  19. )
  20. str(df)
  21. str(type_convert(df))
  22. df <- data.frame(x = c("NA", 10), stringsAsFactors = FALSE)
  23. str(type_convert(df))

3. parse_*: 字符向量转换

  1. parse_integer(c("1", "2", "3"))
  2. parse_double(c("1", "2", "3.123"))
  3. parse_factor(c("a", "b"), letters)
  4. parse_number("$1,123,456.00")
  5. # 空值处理
  6. x <- c("1", "2", "3", "-")
  7. parse_double(x, na = "-")

4. 其他

  1. # 设置中国时间格式、数字分隔符和时区
  2. myloc <- locale(date_names ="zh", decimal_mark =",", tz="PRC" )
  3. parse_datetime(x=Sys.time(), locale=myloc)
  4. # 报错
  5. y <- read_csv("x\n1\n2\nb", col_types = list(col_double()))
  6. y
  7. problems(y)

3. 数据整理

3.1 用基本命令查看数据并做初步处理

  1. rm(list=ls())
  2. # 查看数据情况
  3. data(iris)
  4. dim(iris) # 几行几列
  5. nrow(iris); ncol(iris)
  6. colnames(iris) # 指标名称
  7. attributes(iris) # 数据性质
  8. str(iris) # 数据结构
  9. summary(iris)
  10. # 剔除缺失值和异常值样本
  11. set.seed(1)
  12. a=rnorm(100); b=a+rnorm(100) # 生成模拟数据
  13. a[c(2, 3)]="NA" # a有4个缺失值 NA 和 NULL
  14. a[c(4, 5)]="NULL"
  15. b[50]=10*max(b) # b有异常值
  16. simdata=data.frame(id=seq(1,100),a=a,b=b)
  17. head(simdata)
  18. str(simdata) # 发现a是因子变量
  19. simdata$a=as.numeric(as.character(a)) # 把a转换成数值变量
  20. na.fail(simdata) # 检测向量、矩阵、数据框中是否包含NA数值,如果包含返回错误信息
  21. simdata=na.omit(simdata) # 去掉有缺失值的样本
  22. varplot=c("a","b") # 需要作图的指标
  23. par(mfrow=c(1,length(varplot))) # 设置窗口
  24. for (i in varplot) boxplot(simdata[,i], main=i) # 做箱线图,发现b有异常值
  25. outlier=abs(simdata$b-mean(simdata$b))>3*sd(simdata$b) # 异常值所在行的逻辑向量
  26. simdata=simdata[-which(outlier),] # 去除异常值
  27. summary(simdata)

3.2 用 tidyrdplyr 包处理数据

1. 为什么用 tidyrdplyr

- Classroom data are like teddy bears and real data are like a grizzley bear with salmon blood dripping out its mouth.(Jenny Bryan)
- Up to 80% of data analysis is spent on the process of cleaning and preparing data. (Wickham, 2014 and Dasu and Johnson, 2003)
- `tidyr` & `dplyr` provide fundamental functions for cleaning, processing, & manipulating data, making 95% of your data wrangling tasks much easier!(Brad Boehmke, 2015)

2. 基本思想:化整为零、逐步处理

  1. library(babynames)
  2. library(tidyr)
  3. library(dplyr, warn.conflicts = FALSE)
  4. a=babynames %>%
  5. filter(name == "Hadley") %>%
  6. group_by(year) %>%
  7. summarise(total = sum(n)) %>%
  8. arrange(desc(year))
  9. b0 <- babynames
  10. b1 <- filter(b0, name == "Hadley")
  11. b2 <- group_by(b1, year)
  12. b3 <- summarise(b2, total = sum(n))
  13. b4 <- arrange(b3, desc(year))
  14. # 该命令还可以用于函数,如计算x1和x2之间的欧氏距离
  15. x1 <- 1:5; x2 <- 2:6; sqrt(sum((x1-x2)^2))
  16. (x1-x2)^2 %>% sum() %>% sqrt()

主要命令一览

3. tidyr

  1. tb <- read_csv("tb.csv")
  2. class(tb)
  3. head(tb)
  4. ## 把 m04 (男-4岁)等列指标转换为 demographic = 指标名, n = 指标值的行样本
  5. tb2 <- tb %>%
  6. gather(demographic, n, m04:fu, na.rm = TRUE)
  7. tb2
  8. ## 把 demographic 分为 sex 和 age 两个指标
  9. tb3 <- tb2 %>%
  10. separate(demographic, c("sex", "age"), 1)
  11. tb3
  12. ## 重命名、排序
  13. tb4 <- tb3 %>%
  14. rename(country = iso2) %>%
  15. arrange(country, year, sex, age)
  16. tb4

4. dplyr

  1. library(dplyr)
  2. library(hflights)
  3. data(hflights) # 调用航班数据
  4. flights <- tbl_df(hflights) # 生成本地数据
  5. glimpse(flights) # 查看数据情况
  1. filter(flights, UniqueCarrier %in% c("AA", "UA"))
  2. filter(flights, Month==1, DayofMonth==1)
  3. filter(flights, Month==1 | DayofMonth==1)
  1. select(flights, DepTime, ArrTime, FlightNum)
  2. select(flights, Year:DayofMonth, contains("Taxi"), contains("Delay"))
  1. flights %>%
  2. select(UniqueCarrier, DepDelay) %>%
  3. arrange(desc(DepDelay)) # DepDelay指标的降序,升序为arrange(DepDelay)
  1. flights <- flights %>% mutate(Speed = Distance/AirTime*60)
  1. # 按Dest分组,计算平均ArrDelay
  2. flights %>%
  3. group_by(Dest) %>%
  4. summarise(avg_delay = mean(ArrDelay, na.rm=TRUE))
  5. # 计算组内多个指标的情况,n()为组内样本量,n_distinct(TailNum)为counts the number of unique items in TailNum
  6. flights %>%
  7. group_by(Dest) %>%
  8. summarise(flight_count = n(), plane_count = n_distinct(TailNum))
  9. # 分组对多个变量Cancelled, Diverted,计算统计指标mean
  10. flights %>%
  11. group_by(UniqueCarrier) %>%
  12. summarise_each(funs(mean), Cancelled, Diverted)
  13. # 分组对一个变量Delay计算多个指标min、max
  14. flights %>%
  15. group_by(UniqueCarrier) %>%
  16. summarise_each(funs(min(., na.rm=TRUE), max(., na.rm=TRUE)), matches("Delay"))
  17. # 分组观察一个变量的统计表(number of cancelled and not cancelled flights)
  18. flights %>%
  19. group_by(Dest) %>%
  20. select(Cancelled) %>%
  21. table()
  1. # 每架飞机在1年中的哪两天延误时间最长 top_n(2) 等同于filter(min_rank(desc(DepDelay)) <= 2)
  2. flights %>%
  3. group_by(UniqueCarrier) %>%
  4. select(Month, DayofMonth, DepDelay) %>%
  5. top_n(2) %>%
  6. arrange(UniqueCarrier, desc(DepDelay))
  7. # 计算每个月飞行的航班数和变动情况
  8. flights %>%
  9. group_by(Month) %>%
  10. summarise(flight_count = n()) %>%
  11. mutate(change = flight_count - lag(flight_count))
  1. flights %>% sample_n(5) # 抽5个样本
  2. flights %>% sample_frac(0.25, replace=TRUE) # 抽25%样本

4. 应用举例

  1. rm(list=ls())
  2. # 读取银行贷款数据
  3. loan=read_excel("loan.xls")
  4. str(loan) # 发现变量名有误:(1)先打开数据,选中要复制的表头;(2)运行以下命令将表头复制到timevec
  5. timevec=read.table("clipboard", sep = "\t", header = T) # 从内存剪贴板中读取数据
  6. colnames(loan)=c("var","freq",colnames(timevec)) # 更改变量名
  7. # 用 `tidyr` 和 `dplyr` 包的命令整理
  8. loan_year= loan %>%
  9. filter(freq == "年") %>% select(-freq) %>%
  10. separate(var,c("bank","var"))%>% # 将原来的 "银行名:贷款总额" 拆为两个新变量
  11. select(-var)%>% # 用 table(loan_year$var) 查看后删除 var
  12. gather(time, loan_vol, -bank, na.rm =T) %>%
  13. mutate(time=gsub("X","",time))%>% # 将原来的 "X2000.12" 中的 X 去掉
  14. separate(time,c("year","month"))%>% # 将 "2000.12" 拆为年和月
  15. mutate(year=as.numeric(year))%>% # 字符改为数值
  16. select(-month)%>% # 用 table(loan_year$month) 查看后删除 month
  17. arrange(bank,year) # 按银行名和年份排序
  18. str(loan_year)
  19. loan_quar=loan %>%
  20. filter(freq == "季") %>% select(-freq) %>%
  21. separate(var,c("bank","var"))%>%select(-var)%>%
  22. gather(time, loan_vol, -bank, na.rm =T) %>%
  23. mutate(time=gsub("X","",time))%>%
  24. separate(time,c("year","month")) %>%
  25. mutate(year=as.numeric(year)) %>%
  26. mutate(quar=as.numeric(month)/3) %>% # 用 table(loan_year$quar) 查看是否正确
  27. select(bank,year,quar,loan_vol)%>% # 按顺序选择变量
  28. arrange(bank,year,quar) # 按银行名、年份和季度排序
  29. str(loan_quar)

参考材料

  1. R.I. Kabacoff著:《R语言实战(第2版)》,王小宁、刘撷芯、黄俊文译,人民邮电出版社,2016
  2. 张良均、云伟标、王路、刘晓勇著:《R语言数据分析与挖掘实战》,机械工业出版社,2015
  3. Yollin, G.: R Programming for Quantitative Finance, Lecture Notes
  4. Boehmke, B. 2015: Data Wrangling in R, Online Lecture
  5. Boehmke, B. 2015: Data Processing with dplyr & tidyr, Online Lecture
  6. Rstudio Webinars: Pipelines for data analysis in R, Online Lecture
  7. Rstudio: Data Wrangling Cheat Sheet
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注