美文网首页产品经理数据可视化大数据
基于shinydashboard开发的数据产品监控平台

基于shinydashboard开发的数据产品监控平台

作者: 真依然很拉风 | 来源:发表于2019-06-08 23:52 被阅读204次

    0. 前言

    这是本人第3个基于shinydashboard开发的数据产品(前2个见基于R shinydashboard的道路交通可视化案例比特币智能对冲策略平台);相对于第1篇的炫技、第2篇的神叨,这一个具备相对最为完整的产品逻辑、最为简洁(不为了show什么而做什么),同时也是最为实用的产品。此文从产品、数据、开发的角度来总结一下经验。

    产品全型如下图所示:


    数据产品监控平台

    1. 背景

    对于产品而言,数据是既是其脉象,也是其指南;对于数据产品而言亦然。数据产品模块(如报表)不能仅仅只是交付后就完事,还必须要作后续数据监控,至少有以下几点意义:

    • 了解当前的业务重点,业务人员主要在关注什么数据
    • 了解当前业务的变化趋势,哪些业务数据访问增长,哪些减少
    • 了解每一条业务线报表的核心用户,这些人决定了这些业务线的数据需求
    • 数据产品收益评价,哪些有较高的价值,哪些较小。如果收益较小,是数据产品的问题还是数据需求本身的问题?

    2. 产品设计

    数据来自于后端同学的日志数据,尽管他们有现成的平台可监控,但一方面非结构数据的查询并不是太简单方便,另一方面自己想要的一些逻辑计算并没有现成的模块可直接查询——考虑成本和收益,主要是我一个人在使用,不便占用开发资源——所以就自己写一个平台。

    2.1 指标体系

    日志数据就4个字段(日期、用户、报表、访问量),所以翻来覆去也就那几点排列组合的指标。

    类型 字段 口径 备注
    维度 日期(visit_date) 衍生日、周、月粒度数据
    报表(report_id)
    用户(visit_user)
    指标 PV SUM(visit_num)
    UV COUNT(DISTINCT CASE WHEN visit_num >0 THEN visit_user END)
    访问报表数 COUNT(DISTINCT CASE WHEN visit_num >0 THEN report_id END)
    表均PV PV/访问报表数 单位报表的查询深度
    表均UV UV/访问报表数 单位报表服务广度
    人均PV PV/UV 单位用户的查询深度

    2.2 产品模块

    在这个平台中,核心的数据模块主要有以下模块:

    2.2.1 导航栏

    dashboard必备元素。shinydashboard默认的导航栏布局左侧,左上方为dashboard标题,右侧有一个显示/隐藏按钮;然后控件都是从上到下排列。

    导航栏

    2.2.2 核心指标看板

    核心指标看板

    根据筛选条件计算的核心指标,以看板(big number)的形式一眼对报表访问现状有一个非常直观的认识。

    2.2.3 核心指标趋势

    核心指标趋势

    核心指标的序列波动趋势,作整体监控用,如果核心指标有明显的非周期性波动趋势,意味着需要找业务方聊聊了。

    2.2.4 报表&核心用户排行分布

    报表&核心用户排行分布

    无论是业务数据报表,还是核心用户,一定是符合二八定律的:真正的核心始终只是一小部分。通过排行分布分析,可以直接观察到哪些业务报表,哪些用户是真正的核心,从而为需求管理(哪些业务线的需求须尽力支持,哪些则可以往后拖)、需求挖掘(应该找哪些人聊业务和数据,挖掘抽象出产品化需求)提供指引。

    2.2.5 访问明细追踪

    报表访问记录明细,可以通过搜索,快速追踪某一个报表或者某一个用户的访问明细,作定向观察。


    访问明细追踪

    3. shinydashboard开发仪表盘

    shinydashboard是一套为数据分析师快速搭建数据产品的框架,与常规的数据平台不同,它可以不需前后端分别开发以及联调的过程,一个人(通过各种调包)就能快速搭建出一个MVP出来(比如这个平台的开发调试只用了一个周末);同时与开发语言相对,亦能充分发挥R统计建模的优势。

    shiny分2部分:ui.R(对应前端结构)和server.R(对应后端逻辑)。ui.R里定义前端部分,包括页面结构、交互效果、读取后端接口展示内容;server.R里则主要进行数据连接、数据处理、数据建模与计算、数据可视化,然后将结果传输给前端展现。

    3.1 前端ui.R

    此产品中ui.R代码如下,除了调包和括号部分,核心代码不超过50行;R作为一门高级(调包)语言,其书写简洁的优势在这里体现得淋漓尽致。

    library(RMySQL)
    library(shiny)
    require(shinydashboard)
    library(shinyWidgets)
    library(highcharter)
    library(dplyr)
    library(dashboardthemes)
    library(highcharter)
    library(stringr)
    library(DT)
    library(xts)
    library(ggplot2)
    library(plotly)
    library(ggthemes)
    
    ui <- fluidPage(
      dashboardPage(
        dashboardHeader(title = iconv("数据产品访问监控",to = "UTF-8"),titleWidth = 260),
        dashboardSidebar(
          dateRangeInput(label = iconv("日期范围",to = "UTF-8"),inputId = "date_range",start = Sys.Date()-30,end = Sys.Date(),max = Sys.Date(),language = "zh-CN"),
          sidebarMenu(
            menuItem(iconv("公共报表",to = "UTF-8"), tabName = "report", icon = icon("chart-area")),
            menuSubItem(icon = NULL,textInput(inputId = "report_search",label = iconv("搜索报表id或名称",to = "UTF-8")))
          ),width = 260),
        dashboardBody(
          shinyDashboardThemes(
            theme = "grey_light"
          ),
          tabItems(
            tabItem("report",
                    fluidRow(
                      valueBoxOutput("total_report_num",width = 4),
                      valueBoxOutput("total_report_pv",width = 4),
                      valueBoxOutput("total_report_uv",width = 4),
                      valueBoxOutput("pv_per_report",width = 4),
                      valueBoxOutput("uv_per_report",width = 4),
                      valueBoxOutput("pv_per_uv",width = 4)
                 ),
                    fluidRow(
                      tabBox(width = 12,title = "报表访问核心指标趋势",
                        side = "right", 
                        selected = "报表PV",
                        tabPanel("人均PV", highchartOutput("report_pv_per_uv")),
                        tabPanel("表均UV", highchartOutput("report_uv_per_report")),
                        tabPanel("表均PV", highchartOutput("report_pv_per_report")),
                        tabPanel("报表数", highchartOutput("report_num")),
                        tabPanel("报表UV", highchartOutput("report_uv")),
                        tabPanel("报表PV", highchartOutput("report_pv"))
                      )
                  ),
                 fluidRow(
                   tabBox(width = 12,title = "报表访问排行",
                          side = "right", 
                          selected = "PV排行",
                          tabPanel("核心用户排行",plotlyOutput("report_rank_user")),
                          tabPanel("人均PV排行", plotlyOutput("report_rank_pv_per_uv")),
                          tabPanel("UV排行", plotlyOutput("report_rank_uv")),
                          tabPanel("PV排行", plotlyOutput("report_rank_pv"))
                   )),
                  fluidRow(
                    box(title = iconv("报表访问记录",to = "UTF-8"),dataTableOutput("report_visit_dataset"),collapsible = T,width = 12)
                  )
            )   
          )
        )
      )
    )
    
    3.1.1 dashboard架构

    对比一上面图中的产品布局,以及代码结构,可以显然发现ui.R的架构(事实上,这也是shinydashboard开发数据产品的一般架构)很简单:头部+导航栏+主体,标题在头部,抽屉菜单在导航栏中,控件既可以放在导航栏内也可以放在主体里;主体里可以设定主题(既可以调包,也可以自己连CSS;当然作为调包侠自然是拒绝自己造轮子),可以设置tab,可以赛box,里面可以装看板、文字、数字、图形、表格等元素,取决于前后端接口传输的是什么。

    ui的架构
    3.1.2 前后端接口

    shiny作为一款交互式平台开发框架,与用r markdown开发静态html最主要的区别就在于交互性,即是用户可以通过前端界面做一些操作,然后转化成逻辑条件,传给服务端进行计算,然后服务端将交互计算的输出结果再传回前端展示。所以这个流程和代码里都会涉及到inputoutput部分。

    举一个简单的例子,对于一张交互式表格,当用户在一个下拉框中选择了某一个维度的值进行切片,则交互流程如下图:

    交互流程

    在shiny中的伪代码则如下:

    selectInput(inputId = "s", label, choices) # 前端下拉框
    box(tableOutput(outputId = "tb")) # 前端表格
    output_df <- df %>% filter(x == input$s) %>% reactive # 后端读前端传回的值
    output$tb <- output_df() # 后端计算结果传给前端展示
    
    3.1.3 数据可视化

    数据可视化的代码其实是在server.R里,ui.R只调用可视化产出结果。不过数据可视化本来就属于前端领域,因此还是放在这里论述。

    除了统计建模,数据可视化也是R强大的优势之一。R里也移植了许多优秀的javascript的可视化包,如highcharterrChartsRecharts等。但大道至简(一招鲜吃遍天),我们用万能的ggplot2+plotly即可:ggplot2保证图形结构,plotly使图形变得可交互。

    plotly除了静态的ggplot2图形可hover显示数值外,还有强大的缩放功能。比如核心用户排行模块中,用户间有很明显的长尾效应(可以看到有一个人贡献的PV显著高于其他人,没错这个人就是我),想观察哪些用户不活跃,这些不活跃用户间有多大程序的差异,在下面的图中并不能一目了然。

    整体核心用户排行

    但我们通过局部缩放,就很方便观察这些长尾用户的分布。


    长尾用户分布

    3.2 后端server.R

    3.2.1 交互对象

    除了数据可视化部分,server.R里基本就是数据处理、统计和计算(熟练掌握R基本语法以及dplyr等数据处理包)——这是数据分析、数据开发的基本功,无需阐述。

    但要注意的就是:需要区分对象是静态的还是交互的,凡是用到前端传回传值计算的变量,必须用reactive()转化成交互对象,后续调用时必须以函数形式调用()

    比如上面一段伪代码,因为用到了前端传回的下拉框的交互值来计算,所以output_df必须要经过reactive()转化,后续赋值时,调用的也是output_df()

    3.2.2 输出结果

    后端结果必须通过以类似于render开头的接口才能传给前端,以下是上面的核心用户排行柱状图代码。report_rank_user是前端box里的outputId(对应上面ui.R代码里tabPanel("核心用户排行",plotlyOutput("report_rank_user"))那一行),renderPlotly是plotly包里将ggplot2图形转化交互图形后回调给前端的输出函数。

    output$report_rank_user <- renderPlotly({
        df_report_rank_user <- df_report_visit_by_report() %>% group_by(visit_user) %>% summarise(visit_num = sum(visit_num)) %>% as.data.frame
        df_report_rank_user$visit_user <- factor(df_report_rank_user$visit_user,levels = df_report_rank_user$visit_user[order(df_report_rank_user$visit_num,decreasing = T)])
        
        bar_rank_user <- ggplot(data = df_report_rank_user,aes(x = visit_user, y = visit_num))+
            geom_bar(stat = "identity",fill = "steelblue")+
            labs(x = "",y = "pv")+
            theme_hc()+
            theme(axis.text.x = element_blank(),axis.ticks.x = element_blank(),plot.background = element_rect(fill = "transparent"),panel.background = element_rect(fill = "transparent"))
        ggplotly(bar_rank_user)
    })
    

    3.3 产品发布

    shiny有2种部署方式:一种是在自己的服务器上部署,这样相对麻烦一点,不过还是强烈推荐这一种方式,因为第二种太坑;第二种就是通过Rstudio在shinyapps.io上传,这样能省掉搭建环境的成本,不过至少有3大坑:

    • shinyapps.io在国内访问速度奇慢无比,能不能打开,多久能打开得靠人品
    • 所有的中文必须以UTF-8编码转化,否则报错;当然为了彻底解决这个问题,无论是代码,还是数据里,最好压根就没有中文(R是一门对中文不友好的语言,这一点比Python3差得远)
    • 如果server.R里连接了数据库,则需要在数据库配制文件里增加rstudio服务器白名单,这样其实也很麻烦,而且还有数据安全问题

    因为这个数据产品监控平台主要是我自己用,所以就不部署,每次只在本地上通过rstudio启动

    4.产品价值

    数据产品的价值在于降低数据获取、计算、展示的成本,提高快速数据分析,获取insight的效率——而这个数据产品是能达到这个目标的。

    数据平台访问日志数据原来存储在开发人员的非结构化搜索引擎里,而非技术人员想要获取、分析这些数据,有着明显的学习和使用成本,因此这一部分数据尽管本身是有价值的,却没有得到充分利用。通过这样一个数据产品监控平台,则显著地降低了这样的成本,使我自己(当然如果部署了也包括别人)能快捷、方便地掌控数据产品使用情况,为数据产品生命周期管理,健康的新陈代谢提供了坚强的支撑和驱动。

    5. 参考资料

    相关文章

      网友评论

        本文标题:基于shinydashboard开发的数据产品监控平台

        本文链接:https://www.haomeiwen.com/subject/asuwxctx.html