小白学R—复杂数据处理

这一关属于进阶关,难度相比前面提高了不少,所以花费的时间也多了一些。
本关的学习内容主要为:如何编写函数;数据处理:dplyr, ggplot2;如何编写业务模块;代码如何调试。

1.如何编写函数

1.1 自编函数模板

my_fun <- function(arg1,arg2,...){
  body
  ruturn(data)
  }

例如下面,若add(1,2),结果z=3

add <- function(x,y) {
  z <- x+y
  return(z)
}

1.2 控制语句-循环和条件

1.2.1 for 循环的基本模板

for(i in data){
  body
}

假设有一项重复性工作,如下:

library(stringr)
print(str_c("第几次吃饭",1,sep=":"))
print(str_c("第几次吃饭",2,sep=":"))
print(str_c("第几次吃饭",3,sep=":"))

重复去写1,2,3,...会很麻烦,我们可以用for循环来简化:

for(i in 1:3) {
  print(
  str_c("第几次吃饭",i,sep=":")
  )
  }

1.2.2 while循环的基本模板

while (condition){
  body
}

例如:

i <- 10
while(i>0){
  print(
    i <- i-1)
  }

注意:while 一定要有循环结束的判断条件,否则会无限循环下去。

1.2.3 条件语句的基本模板

if(condition){
  body
}else{
  body
}

例如钱包内有100,吃饭花费30,余额提醒:

money <- 100
if(money>0){
  money <- money-30
  print("钱包还有钱,不需要取钱")
}else{
  print("钱包没有钱,去取款机吧")
}

再举一个复杂点的例子:饭卡余额1000,每天吃3顿饭,每顿5元,余额低于5元,提示:

everday <- function(eatNumber,money){
  for(i in eatNumber){
    eatNumber <- str_c("今天吃第几次饭:",i,sep="")
    money <- money-5*i
    print(money)
    print(eatNumber)
  }
  if(money<5){
    print("饭卡没钱了:去银行取钱")
  }else{
      print("饭卡还有钱:不用去银行")
    }
}

2.数据处理-dplyr、ggplot2

dplyr是一套数据处理工具,它提供了多个函数来帮助你完成常见的数据处理工作:

  • mutate()函数对已有列进行数据运算并添加为新列,类似transform()
  • select()根据列名选择出需要的子集
  • filter()基于数值挑选对象,可以按给定的逻辑条件筛选符合要求的子数据集
  • summarise()对数据框调用函数进行汇总操作, 返回一维的结果
  • arrange()按给定的列名依次对行进行排序,默认为升序,类似order()
    ggplot2是R中重要的绘图工具:
  • ggplot2的核心理念是将绘图与数据分离,数据相关的绘图与数据无关的绘图分离
  • ggplot2是按图层作图
  • ggplot2保有命令式作图的调整函数,使其更具灵活性
  • ggplot2将常见的统计变换融入到了绘图中。
    接下来,我们利用一个例子,来深入学习这两个包。

2.1 数据分析流程

数据预分析步骤:理解数据-数据导入-数据预处理-数据计算-数据显示。

2.1.1 数据导入

首先加载包和数据集。

install.packages("dplyr")
install.packages("nycflights13")
library(dplyr)
library(nycflights13)

2.1.2 数据预处理步骤

进行数据预处理的步骤:选择子集-列重命名-删除缺失数据-处理日期-类型转换-数据排序。

2.1.2.1 选择子集

确定分析目标:航班航线距离与延误时间的关系

# 查看数据结构
str(flights)
myFlights <- select(flights,year,month,day,
                    dep_delay,arr_delay,distance,dest)
# select也可以进行模糊匹配
select(data,
       starts_with("abc"),    #以abc开头
       ends_with("xyz"),      #以xyz结尾
       contains("ijk"),       #包含ijk
       matches("(.)\\1"))     #正则表达式,字符或数据匹配

2.1.2.2 列名重命名

myFlights <- rename(myFlights,destination=dest)  
#tips:新列名在前,旧列名在后

2.1.2.3 删除缺失数据

myFlights <- filter(myFlights,!is.na(dep_delay),!is.na(arr_delay))

filter()更多用法:

# 查找数据
filter(myFlights,month==12,day==25)  #查找12.25的航班
filter(myFlights,arr_delay>120|dep_delay>120)  #延误超2h的航班

2.1.2.4 数据排序

这里我们用的是dplyr中的arrange()函数,默认为升序,desc()让表示降序。

arrange(myFlights,dep_delay)
arrange(myFlights,desc(dep_delay))

2.1.3 数据计算

用dplyr包的分组函数group_by()和组合函数summarise()来进行计算。
数据处理的一般模式: Split(数据分组) - Apply(应用函数) - Combine(组合结果)

# 按照目的地进行分组
by_dest <- group_by(myFlights,destination)
# 求平均到达延误时间和平均航行里程
 delay <- summarise(by_dest,
                    count=n(), #航班数-每个分组有多少数据
                    dist=mean(distance,na.rm = TRUE),
                    delay=mean(arr_delay,na.rm=TRUE)) 
 # 移除噪音数据--移除样本数量较小的数据
 delay <- filter(delay,count>20)
 以上的过程,可以利用管道:%>% 进行简化
 delays <- flights%>%
   group_by(dest)%>%
   summarise(
     count=n(),
     dist=mean(distance,na.rm = TRUE),
     delay=mean(arr_delay,na.rm = TRUE)
   )%>%
   filter(count>20)

2.1.4 数据显示

数据显示要用到绘图包ggplot2,ggplot()是一个图层一个图层来绘制图形的,用其中的加号"+"来结合各个图层,ggplot2绘图的一般模板为:

# ggplot(data =  ) +  #创建画板
#   (mapping=aes( ))  #添加图层

应用到本实例中,ggplot()括号内的参数是要使用的数据,然后是geom_point(mapping = aes(x = dist, y = delay)),这是用来绘制散点图的,x轴为距离dist,y轴为延迟时间delay。 geom_smooth(mapping = aes(x = dist, y = delay))用来给图加入平滑的曲线,以展示x和y的关系。

ggplot(data=delay)+
  geom_point(mapping = aes(x=dist,y=delay))+
  geom_smooth(mapping = aes(x=dist,y=delay))

3.如何编写业务模块

3.1 模块介绍

一个项目通常会有以下几个模块:

  • 视图模块(view):数据显示的实现代码
  • 业务逻辑模块(service):数据处理的代码
  • 数据层模块(db):数据分析要连接的数据库
    各个模块的文件会放在相同名字的文件夹里面,根据需要还可以创建其他模块:
  • 公共模块(util):放项目的公共材料,比如项目的配置信息
  • 公共数据(data):数据分析用到的数据
  • 日志模块(log):数据处理流程
  • 数据输出模块(output):放数据分析的结果,比如绘制的图形和Excel文件等
    例如本例中,util里的packageManager.R代码:
#管理安装包
# 数据包
packages <- c("nycflights13")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}
#字符串包
packages <- c("stringr")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}
#图形包
packages <- c("ggplot2")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}
#数据处理包
packages <- c("dplyr")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
install.packages(setdiff(packages, rownames(installed.packages()))) 
}

3.2 业务逻辑模块

在业务逻辑模块的文件夹(service)里创建R脚本flight.R:

install.packages("dplyr") 
install.packages("nycflights13") 
library(dplyr)
library(nycflights13)# for data
#航班航行距离与延误时间的关系
#输入:不需要输入参数
#输出:返回每个目的地的平均航行距离,平均延误时间
disDelay <- function(){
#选择子集
myFlights <- select(flights,
                    year,month,day,
                    dep_delay,arr_delay,
                    distance,dest)
#列名重命名,等号左边是新列名,右边是就列名
myFlights <- rename(myFlights, destination = dest)
#删除缺失数据,这里的空值NA代表航班取消
myFlights <- filter(myFlights, 
!is.na(dep_delay), 
!is.na(arr_delay))
#数据排序
myFlights <- arrange(myFlights, desc(dep_delay))
#数据计算:航班航行距离与延误时间的关系    
delay <- myFlights %>% 
  group_by(destination) %>% 
  summarise(
    count = n(),
    dist = mean(distance, na.rm = TRUE),
    delay = mean(arr_delay, na.rm = TRUE)
) %>% 
  filter(count > 20)
return(delay)
}

3.3 视图模块

在视图模块文件夹(view)里把前面的数据显示实现代码(flightView.R)存入:

library(ggplot2) 
library(stringr)
#获取当前项目运行根路径
projectPath <- getwd()
#获取service路径
servicePath <- str_c(projectPath,
                   "service",
                   "flight.R",
                   sep="/")
#编译R文件,利用source()调用外部代码并运行
source(servicePath)
#业务逻辑:航班航行距离与延误时间的关系
delay <- disDelay()
#绘制散点图
view <- ggplot(data = delay) + 
geom_point(mapping = aes(x = dist, y = delay)) +
geom_smooth(mapping = aes(x = dist, y = delay))
#定义散点图保存路径
outputpath <- str_c(projectPath,"output","delayFlight.jpg",sep="/")
#利用ggsave()来保存散点图到上面的路径中
ggsave(filename=outputpath, plot=view) 

4.代码如何调试

Rstudio中的代码搜索功能,例如想知道业务逻辑模块中的disDelay 具体代码,可以双击选中函数-进入函数定义的地方:Rstudio-Code-Go to Function Definition。
一个简单的代码调试过程:
代码出现错误-错误在哪块代码-理解错误代码大概什么意思-打断点(stop)-编译(source)-重新执行代码-找到错误原因。
写的比较简单,大家可以找一些参考资料学习。

你可能感兴趣的:(小白学R—复杂数据处理)