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_id C_id SCORE
1 1 01 80
2 1 02 90
3 1 03 99
4 2 01 70
5 2 02 60
6 2 03 80
7 3 01 80
8 3 02 80
9 3 03 80
10 4 01 50
11 4 02 30
12 4 03 20
13 5 01 76
14 5 02 87
15 6 01 31
16 6 03 34
17 7 02 89
18 7 03 98

student表

序号 S_id Sname Sage Ssex
1 1 赵雷 1990-01-01
2 2 钱电 1990-12-21
3 3 孙风 1990-05-20
4 4 李云 1990-08-06
5 5 周梅 1991-12-01
6 6 _兰 1992-03-01
7 7 郑竹 1989-07-01
8 8 王菊 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)
    结果:

![简单线性回归结果](https://img-blog.csdnimg.cn/20200630165702565.png?x-oss-
process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTEyNzgxMA==,size_16,color_FFFFFF,t_70)
从结果可以看出,总体回归方程的R方是0.86,解释性较好,F检验拒绝原假设,各系数的T检验也拒绝了原假设,说明两个变量之间存在很强的相关性,并且回归方程拟合较好。
回归方程为 price=1.329new_price+0.02685
在这里插入图片描述

在这里插入图片描述

posted @ 2021-07-06 18:24  老酱  阅读(666)  评论(0编辑  收藏  举报