你好,你需要我帮你做什么吗?

在精细化数据运营过程中,我们需要使用高度定制的数据处理、可视化和分析等手段。这些过程 Excel、Tableau 和企业级报表工具往往无法满足需求,而 R 语言恰好具备这些特点,因此被誉为“数据分析领域的瑞士军刀”。

R 语言具有以下特征:

1. 免费、开源、可扩展:截至 2018-08-02,CRAN(Comprehensive R Archive Network)上的软件包已达到 12858 个,涵盖了贝叶斯分析、运筹学、金融、基因分析、遗传学等多个领域,并且还在持续更新和迭代。

2. 可编程:R 语言是一种解释型语言,可以通过代码控制执行过程,并能与 Python、Java 等语言实现互相调用。

3. 强大的数据操控能力:

- 数据源接入:通过 RMySQL、SparkR、elastic 等软件包,可以从 MySQL、Spark、Elasticsearch 等外部数据引擎获取数据。

- 数据处理:内置 vector、list、matrix、data.frame 等数据结构,并能通过 sqldf、tidyr、dplyr、reshape2 等软件包实现对数据的二次加工。

- 数据可视化:ggplot2、plotly、dygraph 等可视化包可以实现高度定制化的图表渲染。

- 数据分析与挖掘:R 语言是一门由统计学家发起的面向统计分析的语言,通过自行编程实现或第三方软件包调用,可以轻松实现线性回归、方差分析、主成分分析等分析与挖掘功能。

4. 初具雏形的服务框架:

- Web 编程框架:例如不精通前端和系统开发的同学,可以通过 shiny 软件包开发自己的数据应用。

- 服务化能力:例如通过 rserve 包,可以实现 R 与其他语言通信的 C/S 架构服务。

对于以数据为中心的应用来说,Python 和 R 都是不错的选择,两门语言在发展过程中也互有借鉴。“越接近统计研究与数据分析,越倾向 R;越接近工程开发工程环境的人,越倾向 Python”,Python 是一个全能型“运动员”,R 则更像是一个统计分析领域的“剑客”,“Python 并未建立起一个能与 CRAN 媲美的巨大的代码库,R 在这方面具有绝对领先优势。统计学并不是 Python 的核心使命”。各技术网站上有大量“Python VS R ”的讨论,感兴趣的读者可以自行了解和作出选择。

三、R 的数据处理、可视化、可重复性数据分析能力

对于具备编程能力的分析师或者具备分析能力的开发人员来说,在进行一系列长期的数据分析工程时,使用 R 既可以满足“一次开发,终身受用”,又可以满足“调整灵活,图形丰富”的要求。下文将分别介绍 R 的数据处理能力、可视化能力和可重复性数据分析能力。

3.1 数据处理

在企业级数据系统中,数据清洗、计算和整合工作会通过数据仓库、Hive、Spark、Kylin 等工具完成。对于数据运营项目,虽然 R 操作的是结果数据集,但也不能避免需要在查询层进行二次数据处理。

在数据查询层,R 生态现成就存在众多的组件支持,例如可以通过 RMySQL 包进行 MySQL 库表的查询,可以使用 Elastic 包对 Elasticsearch 索引文档进行搜索。对于 Kylin 等新技术,在 R 生态的组件支持没有跟上时,可以通过使用 Python、Java 等系统语言进行查询接口封装,在 R 内部使用 rPython、rJava 组件进行第三方查询接口调用。通过查询组件获取的数据一般以 data.frame、list 等类型对象存在。

另外 R 本身也拥有比较完备的二次数据处理能力。例如可以通过 sqldf 使用 sql 对 data.frame 对象进行数据处理,可以使用 reshape2 进行宽格式和窄格式的转化,可以使用 stringr 完成各种字符串处理,其他如排序、分组处理、缺失值填充等功能也都具备完善的语言本身和生态的支持。

3.2 数据可视化

数据可视化是数据探索过程和结果呈现的关键环节,而R作为一款免费的统计计算和图形软件环境,其绘图(可视化)系统也是其最大的优势之一。目前,R主流支持的有三套可视化系统:

1. 内置系统:包括base、grid和lattice三个内置发行包,这些包以相对比较朴素的方式完成图形绘制。

2. ggplot2:由RStudio的首席科学家Hadley Wickham开发,通过一套图形语法支持,并支持通过图层叠加以组合的方式支持高度定制的可视化。这一理念也逐步影响了包括Plotly、阿里AntV等国内外数据可视化解决方案。截至到2018-08-02,CRAN已经落地了40个ggplot2扩展包。

3. htmlwidgets for R:这一系统是在RStudio支持下于2016年开始逐步发展壮大,提供基于JavaScript可视化的R接口。htmlwidgets for R作为前端可视化(for前端工程师)和数据分析可视化(for数据工程师)的桥梁,发挥了两套技术领域之间的组合优势。截至到2018-08-02,经过两年多的发展,目前CRAN上已经有101个基于htmlwidgets开发的第三方包。

在实际的数据运营分析过程中,可以通过固化常规的图表展现和可视化分析过程来实现代码复用,从而提高开发效率。例如,美团到店餐饮技术部数据团队积累的部分可视化组件示例如下:

基于可视化组件库,一个可视化过程只需要一行代码即可完成,这能极大提升开发效率。例如,上图中最后的四象限矩阵分析示例图的代码如下:

```R

vis_4quadrant(iris, 'Sepal.Length', 'Petal.Length', label = 'Species', tooltip = 'tooltip', title = '', xtitle = '萼片长度', ytitle = '花瓣长度', pointSize = 1, annotationSize = 1)

```

此外,还提供了四象限矩阵分析可视化组件的函数声明。

根据提供的内容,以下是重构后的代码:

```R

vis_4quadrant <- function(df, x, y, label = '', tooltip = '', title = '', xtitle = '', ytitle = '', showLegend = TRUE, jitter = TRUE, centerType = 'mean', pointShape = 19, pointSize = 5, pointColors = colorpalette2, lineSize = 0.4, lineType = 'dashed', lineColor = 'black', annotationFace = 'sans serif', annotationSize = 5, annotationColor = 'black', annotationDeviationRatio = 15, gridAnnotationFace = 'sans serif', gridAnnotationSize = 6, gridAnnotationColor = 'black', gridAnnotationAlpha = 0.6, titleFace = 'sans serif', titleSize = 12, titleColor = 'black', xyTitleFace = 'sans serif', xyTitleSize = 8, xyTitleColor = 'black', gridDesc = c('A区', 'B区', 'C区', 'D区'), dataMissingInfo = '数据不完整', renderType = 'widget') {

# 绘制分组散点图

# 参数:

# df: 数据框;必要字段;需要进行图形绘制的数据,至少应该有三列

# x: 字符串;必要字段;映射到 X 轴的列名,对应 df 的某一列,此列必须是数值类型或日期类型

# y: 字符串;必要字段;映射到 Y 轴的列名,对应 df 的某一列

# label: 字符串;映射到点上的文字注释

# tooltip: 字符串;映射到点上的悬浮信息

# title: 字符串;标题

# xtitle: 字符串;X 轴标题

# ytitle: 字符串;Y 轴标题

# showLegend: bool;定义分区图例是否展示

# jitter: bool;定义是否扰动

# centerType: 字符串;定义中心点类型,mean 代表平均值,median 代表中位数

# pointShape: 整形;定义点型

# pointSize: 数值;定义点大小

# lineSize: 数值;定义线宽

# lineType: 字符串;定义线型

# lineColor: 字符串;定义线色

# annotationFace: 字符串;定义注释字体

# annotationSize: 数值;定义注释字体大小

# annotationColor: 字符串;定义注释字体颜色

# annotationDeviationRatio: 数值;定义注释文本向上偏移系数

# gridAnnotationFace: 字符串;定义网格注释字体

# gridAnnotationSize: 数值;定义网格注释字体大小

# gridAnnotationColor: 字符串;定义网格注释字体颜色

# gridAnnotationAlpha: 数值;定义网格注释文本透明度

# titleFace: 字符串;定义标题字体

# titleSize:

.3 可重复性数据分析

数据运营分析通常是一个重复性的、需要人工参与的过程。在这个过程中,最终会形成一套数据分析框架,这套框架可以适配特定的数据,从而支持企业的决策制定。RStudio 通过 rmarkdown + knitr 的方式提供了一套基于文本编程的数据分析报告生成方案。开发者可以将 R 代码嵌入到 Markdown 文档中执行,并获得渲染结果(渲染结果可以是 HTML、PDF、Word 文档格式)。在实际的数据分析过程中,开发者最终能够形成一套数据分析模板,每次针对不同的数据进行适配,就可以产出一份新的数据分析报告。

rmarkdown 本身具备简单的页面布局能力,并可以使用 flexdashboard 进行扩展。因此,这套方案不仅能实现重复性分析过程,还能实现分析结果的高度定制化展示。可以通过 HTML、CSS、JavaScript 前端三大件对数据分析报告进行展示和交互的细节调整。最终实现人力的节省和数据分析结果的快速、高效产出。

四、R 服务化改造

4.1 R 服务化框架

R 本身既是一门语言,也是一个跨平台的操作环境,具备强大的数据处理、数据分析和数据可视化能力。除了在个人电脑的 Windows/MacOS 环境中充当个人统计分析工具外,还可以运行在 Linux 服务环境中。因此,可以将 R 作为分析展现引擎,外围通过 Java 等系统开发语言完成缓存、安全检查、权限控制等功能,开发企业报表系统或数据分析(挖掘)框架,而不仅仅只是将 R 作为一个桌面软件。

企业报表系统或数据分析(挖掘)框架设计方案如下图所示:

4.2 foreach + doParallel 多核并行方案

作为一门统计学家开发的解释性语言,R 运行的是 CPU 单核上的单线程程序,并且需要将全部数据加载到内存进行处理。因此,与 Java、Python 等系统语言相比,计算性能是 R 的软肋。对于大数据集合的计算场景,需要尽量将数据计算部分通过 Hive、Kylin 等分布式计算引擎完成,尽量让 R 只处理结果数据集;另外也可以通过 doParallel + foreach 方案,通过多核并行提升计算效率。代码示例如下:

以下是根据您提供的内容重构的代码:

```R

library(doParallel)

library(foreach)

registerDoParallel(cores = detectCores())

vis_process1 <- function() {

# 可视化过程1 ...

}

vis_process2 <- function() {

# 可视化过程2 ...

}

data_process1 <- function() {

# 数据处理过程1 ...

}

data_process2 <- function() {

# 数据处理过程2 ...

}

processes <- c('vis_process1', 'vis_process2', 'data_process1', 'data_process2')

process_res <- foreach(i = 1:length(processes), .packages = c('magrittr')) %dopar% {

do.call(processes[i], list())

}

vis_process1_res <- process_res[[1]]

vis_process2_res <- process_res[[2]]

data_process1_res <- process_res[[3]]

data_process2_res <- process_res[[4]]

```

关于图形化数据报告渲染性能的部分,您可以参考以下代码:

```R

# 在数据分析过程中,R 最重要的是充当图形引擎的角色,因此有必要了解其图形渲染性能。针对主流的基于 rmarkdown + flexdashboard 的数据分析报告渲染方案,其性能测试结果如下:

# 系统环境:*4核CPU,8 G内存,2.20GHz主频。*Linux version 3.10.0-123.el7.x86_64。

# 测试方法:测试在不同并发度下、不同复杂度的渲染模式下,重复渲染100次的耗时。

# 测试结果(数据分析报告渲染性能测试):渲染模式 | 并发度 | CPU时间(秒) | GPU时间(秒) | I/O时间(秒) | 总时间(秒) | 总GPU时间(秒) | 总I/O时间(秒) | 总时间(秒) | 总GPU时间(秒) | 总I/O时间(秒) | 总时间(毫秒) | 总GPU时间(毫秒) | 总I/O时间(毫秒) | 总时间(千分比) | 总GPU时间(千分比) | 总I/O时间(千分比) | 总时间(百分比) | 总GPU时间(百分比) | 总I/O时间(百分比) | 总时间(%) | 总GPU时间(%) | 总I/O时间(%) | 总时间(%) | 总GPU时间(%) | 总I/O时间(%) | 总时间(万分比) | 总GPU时间(万分比) | 总I/O时间(万分比) | 总时间(十万分比) | 总GPU时间(十万分比) | 总I/O时间(十万分比) | 总时间((十亿分比)) | 总GPU时间((十亿分比)) | 总I/O时间((十亿分比)) | 总时间((万亿分比)) | 总GPU时间((万亿分比)) | 总I/O时间((万亿分比)) | 总时间((兆分比)) |总GPU时间((兆分比))|总I/O时间((兆分比))|总时间((千兆分比))|总GPU时间((千兆分比))|总I/O时间((千兆分比))|总时间((太字节))|总GPU时间((太字节))|总I/O时间((太字节))|总时间((拍字节))

根据测试结果可知:单应用平均渲染时长在 0.74s 以上,具体的渲染时长视计算复杂度而定。大部分应用能在秒级完成渲染。由于单核单线程模式所限,当并发请求超过 CPU 核数时,渲染吞吐量并不会相应提升。需要根据实际业务场景匹配对应的服务端机器配置,并在请求转发时设置并发执行上限。对于内部运营性质的数据系统,单台 4 核 8 G 机器基本能满足要求。

五、R 在美团数据产品中的落地实践

美团到店餐饮数据团队从 2015 年开始逐步将 R 作为数据产品的辅助开发语言,截至 2018 年 8 月,已经成功应用在面向管理层的日周月数据报告、面向数据仓库治理的分析工具、面向内部运营与分析师的数据 Dashboard、面向大客户销售的品牌商家数据分析系统等多个项目中。目前所有的面向部门内部的定制式分析型产品,都首选使用 R 进行开发。

另外我们也在逐步沉淀 R 可视化与分析组件、开发基于 R 引擎的配置化 BI 产品开发框架,以期进一步降低 R 的使用门槛、提升 R 的普及范围。

下图是美团到店餐饮数据团队在数据治理过程中,使用 R 开发的 ETL 间依赖关系可视化工具:

六、结语

在企业数据运营实践中扮演关键技术杠杆。然而,作为一门面向统计分析的领域语言,R 的发展主要由统计学家驱动。在近年的数据爆发式增长与应用浪潮下,R 得到越来越多工业界的支持。例如,微软收购了基于 R 的企业级数据解决方案提供商 Revolution Analytics。SQL Server 2016 也集成了 R,并从 Visual Studio 2015 开始正式通过 RTVS 集成了 R 开发环境。这些事件标志着微软在数据分析领域对 R 的高度关注。

在国内,由中国统计之都发起的中国 R 会议自 2008 年起已举办了 11 届,推动了 R 用户在国内的发展壮大。截至 2018 年 8 月,美团的 R 开发者大致在 200 人左右。尽管如此,与 Java/Python 等系统语言相比,R 的用户和应用面仍相对狭窄。本文作者撰写的目的是希望为从事数据相关工作的同学们提供一个新的、更具优势的可选项。

本文作者喻灿,现任美团到店餐饮技术部数据系统与数据产品团队负责人。他于 2015 年加入美团,长期从事数据平台、数据仓库、数据应用方面的开发工作。自 2013 年开始接触 R 以来,他在利用 R 快速满足业务需求和节省研发成本方面积累了一定的心得和产出。同时,他还在美团研发和商业分析团队中积极推动 R 的发展。

对于对数据工程和将数据通过服务业务释放价值感兴趣的同学,可以发送简历至 yucan@meituan.com。美团在数据仓库、数据治理、数据产品开发框架、数据可视化、面向销售和商家侧的数据型创新产品层面等诸多未知但有意义的领域都欢迎你的探索和开拓。