R语言入门——从数据导入、数据清洗到数据分析

基本操作(包括读取数据)

设置工作目录

setwd('D://R/')

读取数据文件

listing<-read.csv('listings.csv',header = T,sep = ',',quote = '')
listings<-na.omit(listing)   # 去除所有含缺失值的行

连接mysql数据库

方法一:RMYSQL包----中文会出现乱码

library(RMySQL)
con<- dbConnect(MySQL(),username = 'root',password='123',host="192.168.1.105",port=3306,dbname = 'ex')      # 建立连接
dbSendQuery(con, 'SET NAMES gbk')  # 设置数据库读取编码格式,避免造成中文数据出现乱码的情况
dbGetInfo(con)   # 查询连接信息
dbListTables(con)   # 查询数据库的表
data<-dbReadTable(con,"test_taobao")    # 读整个表
data<-na.omit(data)
data$new_year<-as.numeric(data$yy)
summary(data)
rs <- dbGetQuery(con,'select * from test_taobao')    # 用SQL语句提取数据
dbDisconnect(con)    # 关闭连接

****忽略此内容

方法二:RODBC包建立连接----与数据库连接限制较多,但中文不会出乱码
需要先下载安装ODBC,建立与本机与数据库的连接后,通过建立的连接来进行数据读取
ODBC下载地址:https://dev.mysql.com/downloads/connector/odbc/
安装完成后,再电脑控制面板---管理工具--ODBC数据源(64位)——单击“添加”。选择mysql odbc 5.3 ansi driver
填写需要连接的数据库地址,端口号,选择数据库名
library(RODBC)
conn<-odbcConnect('sunhao',uid = 'root',pwd = '123456')
sqlTables(conn)
result<-sqlQuery(conn,'select * from sunhao')
result

**忽略结束

第一章 R的数据类型和数据类型的操作

数值(numberic)、字符串(character)、逻辑值(logical)、复数(complex)、缺失值(NA)

1 # 数值
‘sunhao’ # 字符串
TRUE # 逻辑型真
FALSE # 逻辑型假
T # 逻辑型真
F # 逻辑型假
1+2i # 复数
is.numeric(listings$price)

is.vector(listings$price)

数据类型中文含义判断函数转换函数
character字符串is.character()as.character()
numeric数值is.numeric()as.numeric()
logical逻辑is.logical()as.logical()
complex复数is.complex()as.complex()
NA缺失is.na()as.na()

向量(vector)、列表(list)、因子(Factor)

向量(向量内部的数据必须是同一种数据类型)
c(1,2,3,4,5,6)    # 向量
c(1:10)           # 向量,取1-10
a <- c('sunhao','haosun','haozi')
a[2] #向量取值
is.vector(a) #判断是否向量

列表(列表内部存的数据类型可以不是同一种数据类型
list_a <- list(student=c('sunhao','pingxinchuan'),score = c(21,31))
list_a
is.vector(list_a)
b <- as.list(a) # 将向量转换为列表
is.list(b)      # 判断是否列表

因子(将向量转化为因子型,用于后面列联表分析及分组型变量的分析)
sex <- c('M','F','M','M','F')
is.factor(sex)
sex_factor <- as.factor(sex)
levels(sex_factor)
levels(sex)   # 输出NULL,因为sex不是因子型数据类型

矩阵(matrix)、数组(Array)、数据框(Data frame)----数组和矩阵的运算涉及到线性代数的知识,暂时不讲

矩阵
matrix_a <- matrix(c(1:10),nrow = 2)
matrix_a
matrix_b <- matrix(c(1:10),nrow = 2,byrow=T)
matrix_b

数组(Array)三维
array1 <- array(1:18,c(3,3,2))
array1
dim1<-c('A1','A2','A3')
dim2<-c('B1','B2','B3')
dim3<-c('C1','C2')
array2 <- array(1:18,c(3,3,2),dimnames = list(dim1,dim2,dim3))
array2
array3 <- array(1:6,c(2,3))
array3


数据框(Data frame)
names <- c('A','B','C','D','E')
english <- c(60,62,80,90,95)
math <- c(80,88,90,65,70)
scores <- data.frame(names,english,math)  # 数据框每一列的数量必须相同
scores  
scores$names   # 取数据框的names变量的值
scores[[1]]    # 取数据框第一列的值

第二章 数据清洗

数据选择(数据框行列的选择、筛选、列操作)

b <- listings[1000,] # 中括号中用,分开,左边是行,右边选列,行列都可以写向量c(1,2,3)传给行,就是取第1,2,3行,传给列则是第一到三个变量(字段)
b <- listings[,c('price','room_type')] # 取listings表的price和room_type变量
b <- listings[c(100,200,300,400),]     # 按向量提取数据,提取第100/200/300/400行的数据
b <- listings[c(100,200,300,400),c('price','room_type')] # 按向量提取数据,提取第100/200/300/400行的price和room_type数据

c <- listings[which(listings$room_type == 'Private room'),]  #  按条件筛选,which返回的是行号
c <- listings[which(listings$room_type == 'Private room' |listings$room_type == 'Entire home/apt'),]  #  按条件筛选,连接两个同时成立的条件用&,两个或关系用|

d <- listings$price^2/1000   # 由于单独取某一列及为向量,向量中如果是数值的话,可以直接做加减乘除等一般的数字计算
library(tidyr)   # tidyr包,合并两列数据,不论是字符串还是数值,
new_lisitngs = unite(listings, "newtype2", room_type, neighbourhood, sep = "/", remove = FALSE)   # 将room_type和neighbourhood变量合并,合并中间加/符号,remove传逻辑值,TURE代表合并后删除原变量,FALSE表示合并后保留原变量

数据分组、分割、合并和变形

tapply(listings$price,list(listings$neighbourhood,listings$room_type),FUN = mean)  # 分组汇总,求各地区各种房型价格的均值,FUN传递需要计算的参数函数。

sc表

序号S_idC_idSCORE
110180
210290
310399
420170
520260
620380
730180
830280
930380
1040150
1140230
1240320
1350176
1450287
1560131
1660334
1770289
1870398

student表

序号S_idSnameSageSsex
11赵雷1990-01-01
22钱电1990-12-21
33孙风1990-05-20
44李云1990-08-06
55周梅1991-12-01
66_兰1992-03-01
77郑竹1989-07-01
88王菊1990-01-20
merge函数链接两个表,all族参数代表是inner join/left join/right join,by族参数代表是on,通过什么来链接。

全链接(左右都要)
all_join <- merge(sc,student,all = T,by.x = 'S_id')

inner join
inner_join <- merge(sc,student,all = F,by.y = 'S_id') 
left join
left_join <- merge(sc,student,all.x = T,by.x = 'S_id',by.y = 'S_id')
right join
right_join <- merge(sc,student,all.y = T,by.y = 'S_id') 

缺失值、异常值和重复值处理

1. 缺失值
1.1查看是否有缺失值
summary(listing) # 使用summary函数,会返回每一列的缺失值数量
1.2删除缺失值行
listings <- na.omit(listing) # 删除listing里面含有缺失值的所有行
1.3替换缺失值
price_mean <- mean(listing$price,na.rm = TRUE)
	1.3.1使用均值代替缺失值
listing$price_new <- ifelse(is.na(listing$price)== TRUE,price_mean,listing$price)# 新建一列变量price_new,如果是缺失值就用均值替代
summary(listing)
	1.3.2.使用前一个数据代替缺失值

	1.3.3.使用后一个数据代替缺失值
2. 异常值
2.1 基于统计分布检验和去除异常值(x的值如果在μ±3s范围外的数据均为异常值)
x_3s <- sqrt(var(listing$price_new))*3
x <- mean(listing$price_new)
x_up <- x+x_3s
x_down <- x-x_3s
listing2 <- listing[which(listing$price_new>x_down & listing$price_new < x_up),]

2.2 基于箱线图去除异常值(x的值从上下四分位数开始,超出1.5倍内距的值,均为异常值)
box_result <- boxplot.stats(listing$price_new)
price_min <- box_result$stats[1]
price_max <- box_result$stats[5]
listing3 <- listing[which(listing$price_new>=price_min & listing$price_new<=price_max),]

3 删除重复数据duplicated(需要不重复的列名)
listing4 <- listing[!duplicated(listing$room_type),]

时间序列数据处理

1. 日期时间格式转换
Sys.Date()   # 输出当前日期 "2020-07-30",返回的是日期格式值
Sys.time()   # 输出当前日期和时间 "2020-07-30 16:05:26 CST",返回的是日期格式值
date()      # 显示当前周几、月份、日、时间、年份,但是不是日期格式的数据,是字符串
is.Date(date())     # lubridate包的方法,可以看出,date()返回的是字符串,不是日期格式的数据

time1 <- as.POSIXlt('2020-07-30 15:33:00') #将标准日期格式的字符串转变为标准时间格式数据
time2 <- as.POSIXct('2020-07-30 15:33:00')  # 以秒存储时间
unclass(time2)
time3 <- as.Date('2020-07-30 15:33:00')    # 只有年月日
unclass(time3) # 返回从1970-01-01到time3的天数,1970-01-01作为0。(可以用作计算两个日期之间相差多少天)

2.输出具体日期年、月、周、季度
weekdays(time1) # 输出星期几
months(time1) # 输出几月
quarters(time1) # 输出第几季度

library(lubridate)  #lubridate日期函数包,传入的值可以不是日期格式,但是形式要是日期形式,自带包的必须传日期格式的数据
year(time1)   # 自带包里没有year函数,只有在lubridate包里面才有
weekdays(time1) # 输出星期几
months(time1) # 输出几月
quarters(time1) # 输出第几季度
day(time1) #输出当月的第几天

3. format函数提取关键信息
a <- Sys.time()
format(a,'%y-%b')   # %d月份中的天数、%m月份(以数字形式)、%b月份(小写数字)、%B月份完整的月份(中文)、%y年份(只显示后两位)、%Y年份(全年份)

第三章 表、图

1. 频数分布表
table(listings$room_type)
prop.table(table(listings$room_type))

2. 列联表
table(listings$neighbourhood,listings$room_type)
prop.table(table(listings$neighbourhood,listings$room_type),1)*100
prop.table(table(listings$neighbourhood,listings$room_type),2)*100

1. 所有的图都有以下参数
主标题main = NULL, 副标题sub = NULL, X轴标题xlab = NULL, Y轴标题ylab = NULL,

2. 柱状图
barplot(table(listings$room_type),horiz = T)  # horiz 默认FALSE,表示柱子垂直,TRUE表示柱子水平
barplot(table(listings$neighbourhood,listings$room_type))
barplot(table(listings$room_type,listings$neighbourhood),horiz = T)

3. 饼图
pie(table(listings$room_type))
pie(table(listings$neighbourhood,listings$room_type))

4. 直方图与核密度曲线
hist(listings$price,freq = F)
lines(density(listings$price),col='red') #核密度曲线

5.箱线图 ---1.5倍内矩外的点就叫做离群点,可以剔除,在图中就是原点的形式
boxplot(listings$price)
boxplot(listings$price~listings$room_type)
boxplot(listings$price~listings$neighbourhood)

boxplot.stats(listings$price)  # 返回list,list$stats返回数据的四分位点及修正后的极值,list$n返回观测值个数,list$conf返回中位数的置信区间,list$out返回箱线图超过极值的离群点
boxplot.matrix(listings$price)
6. 散点图
listings$new_price<-listings$price^2/2300
plot(listings$price,listings$new_price)

7.图形美化
c<-c(2,3,4,5,6,7)
d<-c(2,3,4,5,6,7)
a<-c(1,2,3,4,5,6)

opar<-par(no.readonly = TRUE)   # 生成一个可以修改的当前图形参数列表
par(mfrow=c(1,2))     # 生成1行2列的画布
par(pin=c(2,3))         # 图形的宽,高
par(lwd=2,cex=1.5)   # 图形中先的宽度2,点的大小1.5
par(cex.axis=0.75,font.axis=3)  # 字体大小0.75,字体类型3号
plot(a,c,type='b',pch=19,lty =2,col='red')  #a,c点点图,有点有趋势线,点类型19,线类型2(虚线),线颜色红色
plot(a,d,type='b',pch=23,lty=6,col='blue',bg='green')    # a,d点图,有点有趋势线,点类型23,线类型6,线颜色蓝色,背景颜色绿色
par(opar) # 结束该图表参数列表
https://www.jianshu.com/p/f4fd994b50e0

使用ggplot2包实现画图

library(ggplot2)
listings$newtype<-as.factor(listings$room_type)
1. 散点图
ggplot(listings,aes(x=price,y=new_price))+geom_point(pch=17,size=2,col='red')+geom_smooth(method = 'lm',linetype=2,fullrange=F)+labs(title = '散点图',x='price',y='newprice')
ggplot(listings,aes(x=price,y=new_price))+geom_point()+geom_hline(yintercept = 1000) # 水平线
ggplot(listings,aes(x=price,y=new_price))+geom_point()+geom_vline(xintercept = 1000) # 垂直线
ggplot(listings,aes(x=price,y=new_price))+geom_point()+geom_line() # 连接各点
2. 柱状图
ggplot(listings,aes(x=neighbourhood))+geom_bar()

3.箱线图
ggplot(listings,aes(y=price))+geom_boxplot()   # 垂直的箱线图
ggplot(listings,aes(x=price))+geom_boxplot()   # 水平的箱线图
ggplot(listings,aes(x=newtype,y=price))+geom_boxplot()  # price针对roomtype分组的箱线图

4. 直方图和核密度曲线
ggplot(listings,aes(x=price))+geom_histogram() #直方图频数分布
ggplot(listings,aes(x=price))+geom_histogram(aes(y=..density..))+geom_density() # 直方图频率分布及核密度曲线

5.折线图
ggplot(listings,aes(x=price,y=new_price))+geom_point()+geom_line() # 连接各点

第四章 统计数值描述分析

自带包

summary(listings)  # 数值型数据会把最大值,最小值,均值中位数和四分位数给出,分类型变量会给出数量
summary(listing)   # NA's就是缺失值数

Hmisc包的describe() 没有数量的限制,对因子型变量有统计各水平的频次和频率。

library(Hmisc)
describe(listings)

pastecs包的stat.desc函数 数量在3-5000条-------不推荐使用

library(pastecs)
listings_4999<-listings[1:4999,]
stat.desc(listings_4999$price,norm = T)

psych包中describe()-------------推荐使用

(mad: 绝对中位差;trimmed:切尾均值,切尾比例为0.1)
library(psych)
describe(listings)
describe(listings$price)

第五章 参数估计

点估计—总体均值和总体方差的点估计

summary(listings)
mean(listings$price,na.rm = TRUE) # 一个总体的均值点估计
var(listings$price,na.rm = T) # 一个总体的方差点估计

区间估计—总体均值的

1.计算区间估计上下限

t.test(listings$price,conf.level = 0.99)  # 置信水平conf.level默认为0.95

2.绘制箱线图和直方图,观察分布情况,是否符合正态分布

p<-par(no.readonly = TRUE)
par(mfrow=c(1,2))
hist(listings$price,freq = F)
lines(density(listings$price),col='red')
boxplot(listings$price)
par(p)

3.绘制QQ图检验是否服从正态分布

qqnorm(listings$price);qqline(listings$price)

区间估计—总体方差的

R没有自带的计算方差的包,这里编写chisq.var.test函数来计算

chisq.var.test<-function(x,var,alpha=0.05,alternative='two.sided'){
  options(digits = 4)
  result<-list()
  n<-length(x)
  v<-var(x)
  result$var<-v
  chi2<-(n-1)*v/var
  result$chi2<-chi2
  p<-pchisq(chi2,n-1)
  if(alternative =='less'|alternative=='greater'){result$p.value<-p}else if(alternative=='two.sided'){if(p>0.5)p<-1-p
  p<-2*p
  result$p.value<-p}else return('your input is wrong')
  result$conf.int<-c((n-1)*v/qchisq(alpha/2,df=n-1,lower.tail = F),(n-1)*v/qchisq(alpha/2,df=n-1,lower.tail = T))
  result                   
}
chisq.var.test(listings$price,var(listings$price),0.05)

第六章 假设检验

总体均值的假设检验

单样本T检验

1. 双尾:
t.test(listings$price,mu=400) # conf.level(置信水平)默认0.95

2.单尾:
商业数据分析上看,一般单尾的p值是双尾p值的一半,所以,一般双尾的结果拒绝,那么单尾的结果也会拒绝,所以一般商业数据分析的时候都不做单尾,只做双尾检验。
t.test(listings$price,mu=400,alternative = 'greater')  # alternative参数代表备择下设,如果是greater则是右尾,less则是左尾,two.sided(默认)即双尾

两样本T检验

listings$newtype<-ifelse(listings$room_type=='Entire home/apt','Entire home/apt','other')
1.方差齐性检验--两个总体方差是否相同
var.test(listings$price~listings$newtype)   # 方差齐性检验结果,原假设:两样本方差相同,备择假设:两样本方差不同。
2.两样本T检验--原假设:两样本均值相同,备择假设:两样本均值不同
	2.1两样本方差不同
	t.test(listings$price~listings$newtype,var.equal=F)   # var.equal默认为FALSE,所以如果是方差非齐性的可以直接省略
	2.2两样本方差相同
	t.test(listings$price~listings$newtype,var.equal=T) 

总体成数的假设检验

单样本

(研究Entire home/apt占比的单样本总体成数检验)
listings$newtype <- as.factor(listings$newtype)
a <- summary(listings$newtype)
prop.table(table(listings$newtype))
b <- length(listings$newtype)
prop.test(a[1],b,p = 0.5,alternative = 'two.sided')  # 默认P=0.5,a[1]是成功的次数,b是总的次数,得到结果可以看出,总体成数明显不等于0.5,拒绝原假设,区间估计范围是0.6021214 0.6169395

两样本

(研究东城区和西城区的Entire home/apt方形占比是否相同)
table(listings$neighbourhood,listings$newtype)  # 得到,东城区Entire home/apt房型1641个,总共2363套房子,西城区691套Entire home/apt,总共1094套房子
x <- c(1641,691)
n <- c(2363,1094)
prop.test(x,n,alternative = 'two.sided')

总体方差的假设检验

单样本(R没有自带包的假设检验,需要自带函数)

univariate.var.test = function(x,var,mu=Inf,alternative="two.sided"){
  n=length(x)
  df=n-1   #均值未知时的自由度
  var.est=var(x) #均值未知时的方差估计值
  if(mu<Inf){df=n;var.est=sum((x-mu)^2)/n}# 总体均值已知的情况
  chi2=df*var.est/var.est
  options(digits = 3)
  return(data.frame(Pop.var=var,Samp.var=var.est,df=df,Chi2.stat=chi2,P=2*min(pchisq(chi2,df),pchisq(chi2,df,lower.tail=F))))
  if(alternative=="greater")result$P=pchisq(chi2,df,lower.tail = F)
  else if(alternative=="less")result$P=pchisq(chi2,df)
  result
}
e <- univariate.var.test(listings$price,var(listings$price))
e

两样本

var.test(listings$price~listings$newtype) 

第七章 卡方检验

自带包卡方检验

chisq.test(listings$newtype,listings$room_type)
原假设:两个分组型变量之间没有关系,备择假设:两个分组型变量有明显的关系
如果p值远小于0.05那么就说明拒绝原假设,说明两个分组型变量间相关性很大

prettyR包中的xtab()进行卡方检验

library(prettyR)
xtab(~newtype+room_type,data=listings) 

第八章 方差分析

单因素方差分析

1.将分组型变量转变成因子数据

is.factor(listings$room_type)
listings$new_roomtype <- as.factor(listings$room_type)
is.factor(listings$new_roomtype)

2.按因子分水平查看各水平数据情况

tapply(listings$price,listings$new_roomtype,summary) 
# 按因子分水平查看各水平数据情况,发现各水平均值都不同

3.进行单因素方差分析

anova(lm(listings$price~listings$new_roomtype))   
# 结果P值如果小于0.05则说明该因子对price有显著的影响

4.多重比较(LSD检验)—基于agricolae包

library(agricolae)
model <-aov(price~new_roomtype,data=listings)
model
out <- LSD.test(model,'new_roomtype',p.adj = 'none')
out

多因素方差分析

(一般在探索数据分析中,会将每个变量的交互项都进行分析下,如果没有通过检验,则去除掉交互项再进行无交互项的方差分析)
本例中用room_type和neighbourhood两个变量组进行双因素方差分析
listings$neighbourhood_new<-as.factor(listings$neighbourhood) # 将行政区变量转变成因子变量

无交互项的多因素方差分析

anova(lm(listings$price~listings$new_roomtype+listings$neighbourhood_new))

有交互项的多因素方差分析

anova(lm(listings$price~listings$new_roomtype+listings$neighbourhood_new+listings$new_roomtype*listings$neighbourhood_new))

双因素方差分析的LSD多重比较

library(agricolae)
model <-aov(price~new_roomtype+neighbourhood_new,data=listings)
model
out <- LSD.test(model,c('new_roomtype','neighbourhood_new'),p.adj = 'none')
out

第九章 相关和回归

相关性分析

1.散点图

plot(listings$price,listings$new_price) +
library(ggplot2)
ggplot(listings, aes(x = price, y = new_price)) + geom_point() + geom_smooth(method = "lm") + labs(x = "横坐标标题", y = "纵坐标标题")
ggplot(listings, aes(x = price, y = sqrt(new_price))) + geom_point() + geom_smooth(method = "lm") + labs(x = "横坐标标题", y = "纵坐标标题")

2.计算相关系数(pearson相关系数来看线性相关程度,spearman相关系数来看非线性相关程度)

cor(listings$price,listings$new_price)
cor(listings$price,listings$new_price,method = 'spearman')

3. 相关性的显著性检验

cor.test(listings$price,listings$new_price) # 默认method是pearson相关系数
cor.test(listings$price,listings$new_price,method = 'spearman')

回归分析

简单线性回归(一元线性回归)

1. 先做了相关分析;
2. 计算回归参数及回归方程:

listings<-na.omit(listing)
result<-lm(listings$price~listings$new_price)
summary(lresult)

3. 点预测及计算残差
listings$predict1<-predict(result)
listings$fitted<-fitted(lresult)
listings$resid<-resid(result)

predict和fitted都是点估计的预测方法,计算结果相同
残差项用于后面对残差进行分析

4. 区间预测(result为回归后的结果)
预测区间:result.pred <- predict(result,interval="prediction",level=0.95)
置信区间:result.pred <- predict(result,interval="confidence",level=0.95)
结果:

简单线性回归结果
从结果可以看出,总体回归方程的R方是0.86,解释性较好,F检验拒绝原假设,各系数的T检验也拒绝了原假设,说明两个变量之间存在很强的相关性,并且回归方程拟合较好。
回归方程为 price=1.329new_price+0.02685
在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页