一、数据的写入与写出
1. 数据写入
# 读取 csv 文件
library(tidyverse)
data <- read_csv('data.csv', col_names = TRUE)
# 读取 excel 文件
library(readxl)
data <- read_xlsx('data.xlsx', sheet = 1, col_names = TRUE)
# 读取 PDF 文件
library(pdftools)
data <- pdf_text('data.pdf')
# 读取 json 文件
library(jsonlite)
data <- fromJSON('data.json')
# 读取 dta 文件
library(foreign)
data <- read.dta('data.dta')
# 读取 MySQL
pacman::p_load(DBI, dplyr, RPostgreSQL)
db_connect <- dbConnect(RPostgreSQL::PostgreSQL(),
dbname = '数据库名称', host = '服务器地址',
user = '用户名', password = '密码')
dbListTables(db_connect)
tbl(src = db_connect, dbListTables(db_connect)[1])
# 若数据量特别大
library(data.table)
Data <- fread('data.csv')
2. 数据写出
# 写出为 csv 文件
library(tidyverse)
write_csv(Data, file = "DataName.csv")
# 写出为计量统计表
library(stargazer)
二、数据的清洗与处理
1. 行数据处理
# 取行
data[which(data$numbers < 10), ]
data[which(data$strings == 'abc'), ]
df$col[is.na(df$col)]
df %>% filter(., col1 == 1)
# 插入行
data <- tibble(i = 1:3, j = c('John', 'Sam', 'Joy'))
data$k <- 3:1 # 法一
add_column(data, m = nrow(data):1, .after = 1) # 法二,.after表示插入在第1行后
# 依据 id 去除重复项
data <- data[!duplicated(data[c('id')]),]
# 处理 NA
library(tidyverse)
replace_na(list(value = 'missing')
drop_na()
data = subset(data, colum != 'NA')
# 自动填充
library(tidyverse)
fill(data, x1)
# 拆分单元格
library(tidyverse)
separate_roww(data, x1)
# 压缩/解压缩
library(tidyverse)
nest(-x1)
unest(-x1)
# 分组
library(tidyverse)
df % <% group_by (col_name1) # 按列1进行分组
# 排序
library(tidyverse)
df %<% arrange_if(is.character) # 按df中的字符向量列进行排序
# 从前往后,按col_name1降序、col_name2升序排序,.by_group = T说明分组有效
arrange(Data, desc(col_name1), col_name2, .by_group = T)
# 排列因子顺序
df <- within(df,{col1 <- factor(col1,
levels = c("factor1", "factor2", "factor3"))})
# 筛选
library(tidyverse)
# 按两个col_name筛选,需要同时满足
Data1 <- filter(Data, col_name1 == 1, col_name2 == 1)
# 按两个col_name筛选,满足一个即可
Data1 <- filter(Data, col_name1 == 1 | col_name1 == 2)
# 按逻辑进行筛选
Data1 <- filter(Data, col_name1 < 1000 & co_name1 > 500)
# 关于字符向量的正则筛选以及其他更加复杂的筛选,见R数据科学实践第68页
2. 列数据处理
a. 常规处理
# 取列
df <- data[, c('id', 'col1', 'col2', 'col3')]
# 插入列
data[(nrow(data)+1), ] <- list(4, 'Jon', 0) # 法一
add_row(data, i = 1, j = 'Alan', .before = 2) # 法二,.after表示插入在第2行前
# 重命名
library(tidyverse)
rename(Data, new_name = exist_name)
colnames(seg) <- c('case_number', 'seg')
# 排序
library(tidyverse)
# 将col_name2和col_name3排到所有其他变量之前
Data1 <- select(Data, col_name2, col_name3, everything())
# 仅选择col_name1、col_name2和col_name3
Data1 <- select(Data, col_name1, col_name2, col_name3)
# 若这三列相邻等价于
Data1 <- select(Data, col_name1:col_name3)
# 选择除这三列以外的别的变量
Data1 <- select(Data, -(col_name1:col_name3))
# select的进阶应用见R数据科学实践第74页
# 增删、更新与替换
library(tidyverse)
# 创建新变量
mutate(Data,
col_neme1 = col_name1 / 10, # 将原有行除以10
new_col1 = col_name1 / (col_name2^2), # 数学运算
new_col2 = if_else(new_col1 > 30, 'Yes', 'No'), # 两种逻辑判断
new_col3 = case_when(new_col1 > 30 ~ 'Yes',
new_col1 > 30 ~ 'No'), # 多种逻辑判断
new_col4 = cumsum(col_name1), # 计算之前数字的累计值
new_col5 = cummax(col_name1), # 计算到该行为止的最大值
new_col6 = cummean(col_name1), # 计算到该行为止的平均值
new_col7 = row_number(col_name1), # 按大小计算该行数值在该列的顺序
new_col8 = ntile(col_name1, n = 2), # 按大小顺序均匀的分布到n组
new_col9 = c(NA, diff(col_name1))) # 计算差值
# mutate_if, mutate_at, mutate_all以及其他关于mutate的进阶用法见书第81页
# 创造一列为增长率
df$grow_col_1 <- c(NA, diff(df$col_1))
# 描述性分析
library(tidyverse)
df %>% group_by(col_name1) %>% # 按列1进行分类查看,列1应当是因子型变量
summarise(average = mean(x1, na.rm = T), # 算平均值
numbers = n(), # 算样本数
sd = sd(x1, na.rm = T), # 算标准差
se = sd / sqrt(n), # 算标准误差
max_x1 = max(x1, na.rm = T), # 算最大值
min_x1 = min(x1, na.rm = T), # 算最小值
median_x1 = median(x1, na.rm = T), # 算中位数
range_x1 = max_x1 - max_x2, # 算差值
range = diff(range(x1, na.rm = T)), # 算差值,与上行等价
char = paste(unique(character), # 拼接字符串
collapse = "-"))
df %>% Hmisc::describe(.) # summary()
b. 字符串
# 字符串的剪切
data$b <- substr(data$a, 1, 4) # 取 b 列的前 4 个字符
# 拼接多列字符串 将 string3 列中的 na 设为 a
df$col <- paste(df$string1, df$string2, zoo::na.fill(df$string3, 'a'))
# 替换字符串
df$col <- gsub("a", "b", df$col) # 将 col 列中的 a 替换为 b
df$col <- gsub("a", NA_character_, df$col) # 替换为NA
# 识别字符串中是否有某特定字符串
df <- mutate(df, new_col = case_when(
stringr::str_detect(df$col, "中级") ~ "中级"))
# 拆分列
library(tidyverse)
# 分离某一列的信息
data2 <- data1 %>%
separate(key, into = c('性别', 'key'),
convert = TRUE, sep = " ") # sep = 2则表示在第2个字符后分离
# 合并某两列的信息
data <- data %>% unit(new_name, col_name1, col_name2, sep = "")
c. 时间数据
# 将变量转为时间变量
data$Birthday <- as.Date(Data$Birthday, format = "%Y/%m/%d")
# 将时间解析为易读的格式
library(lubridate)
ymd(c(20180102, '2017-01-02', '2018 1 2'))
# 时间单位提取
library(lubridate)
year(data$x1)
# 时间日期格式分析
library(lubridate)
Date <- c('24 Jan 2018', 1802201810)
guess_formats(Date, c('mdY', 'BdY', 'Bdy', 'bdY', 'bdy', 'dbY', 'dmYH'))
parse_date_time(Date, orders = c('dObY', 'dOmYH', 'dbY', 'dmYH'))
# 计算时间差
三、数据框的转换与合并
1. 数据框转换
# 宽 变 长
library(tidyverse)
# 合并同一数据框的不同列数据
# 其中`year0`, `year1`为原列名,现在将其作为一个新列列名为'year'
data <- data %>% gather(`year0`, `year1`, key = 'year', value = 'cases')
# 长 变 宽
library(tidyverse)
# 合并同一数据框中index重复的项
tidyData <- data %>% spread(key = type, value = count)
2. 数据框合并
# 以 df1 为基础,依据 id 合并
data <- merge(df1, df2, by = "id", all.x = TRUE)
# 合并
library(tidyverse)
bind_rows(df1, df2, .id = 'id') # .id = 'IDs'用于标记来源
# 合并两个不同的数据框,by不是必须的,如果没有则为自然合并
left_join(Data1, Data2, by = "col_name1")