Shiny初试:用wordcould2画用户标签

Shiny是Rstudio里用来做demo的,相当于一个前端框架,可以连接R里的元素。我是这么理解的。一直想试一试Shiny,这次做用户画像,正好可以用它做一个demo给开发同学看,所以就学习了一下它的使用逻辑。目标很简单,这个demo由两个部分组成,第一部分是一个输入框,可以输入会员号。第二部分就是一个标签集(tag cloud),用了wordcloud2包,根据输入的会员号显示这个用户的标签集。大致效果如下:

Shiny初试:用wordcould2画用户标签_第1张图片
用户画像示例

教程看的是Shiny官方的七节课,看完就给人一种错觉,好像自己已经会了。Shiny Gallery里还有一个wordcloud的demo,但这个就看得云里雾里了,根据它的代码改了下,总是报错,因为没有真正掌握Shiny的思路。再研究和尝试了很多下,终于调试出来了。

Shiny的一个app由两个文件构成,一个控制前端显示ui.R,一个控制后台server.R。他们的关系比较复杂,有点像鸡生蛋蛋生鸡的关系。ui.R通过widgets得到用户输入的值,每一个widget需要自定义名称widget_name,用户输入的值就用input$widget_name来引用。然后后台的server.R使用前端输入的值,产生各种output,比如图,表格,输出文本等等。在我们的例子里,前端输入的是会员号,output是一个tag cloud。每一个output的东西也都要命名,比如给我们的tag cloud命名为output$plot,但这个output$plot只是以一个R元素存储了起来,展示的工作还是要交给前端的ui.R。所以这个时候呢,要再回到前端的ui.R去,告诉它我这个plot要放在什么位置,然后要它把这个元素展示出来。到此,就是我理解的shiny的主要思路。

废话不多说,先贴代码。



#### server.R ####

load('C:/app/test0223.RData')
library(wordcloud2)

shinyServer(
    function(input, output) {
      
      output$plot <- renderWordcloud2({

        getdata<-function(cid){
          dataList[[cid]]
        }
        word_color<-getdata(input$selection)
        wordcloud2(word_color$data, size=0.12, fontFamily = '微软雅黑', rotateRatio =0,
                       gridSize=15,  shuffle=F, color = word_color$colorVec )
      })
    }
)

#### ui.R ####

fluidPage(
  # Application title
  titlePanel("Word Cloud"),
  
  # sidebar
  sidebarLayout(
    # Sidebar with a slider and selection inputs
    sidebarPanel(
      selectInput("selection", label = "请输入会员号", 
                  choices = as.list(names(dataList)))
    ),
    
   # Show Word Cloud
   mainPanel(
      wordcloud2Output("plot")
    )
  )
)
代码解释

1
首先简单解释一下wordcloud2包的用法。

wordcloud2(data, size, fontFamily = '微软雅黑', rotateRatio =0,
                       gridSize=15,  shuffle=F)

适用的dataset要有两列,第一列叫word,第二列叫freq,即每个单词的频次。因为这里我只是做一个tag cloud,每个tag的权重都给它1,即不区分大小。如:

word freq
Tag 1 1
Tag 2 1
Tag 3 1
... ...

其他的参数可查询文档。
 
2
load的test0224.RData中包含一个叫dataList的list,它里面有1000个会员的标签信息,结构如下:

str(dataList)
List of 1000
 $ Customer1  :List of 2
  ..$ data    :'data.frame':    20 obs. of  2 variables:
  .. ..$ word: chr [1:20] "Tag 1" "Tag 2" "Tag 3" "Tag 4" ...
  .. ..$ freq: num [1:20] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ colorVec: chr [1:20] "#757575" "#D32F2F" "#212121" "#FFCDD2" ...
 $ Customer2  :List of 2
  ..$ data    :'data.frame':    19 obs. of  2 variables:
  .. ..$ word: chr [1:19] "Tag 1" "Tag 2" "Tag 3" "Tag 4" ...
  .. ..$ freq: num [1:19] 1 1 1 1 1 1 1 1 1 1 ...
  ..$ colorVec: chr [1:19] "#757575" "#D32F2F" "#212121" "#FFCDD2" ...

可以看到dataList里每个元素也都是一个list,包含两个元素,一个data,一个colorVecdata就是上面说的包含了word和freq两列的dataframe,而colorVec是一个和data一样长的character vector,它指示data中每个tag所使用的颜色。如果不指明color,wordcloud2会随机给每个tag一个颜色。我们在这里用颜色来代表不同种类的tag,如基本信息,交易信息等等。
 
3
先看ui.R中的这段代码:

 sidebarLayout(
    # Sidebar with a slider and selection inputs
      sidebarPanel(
        selectInput("selection", label = "请输入会员号", 
                            choices = as.list(names(dataList)))
    ),

我们在侧边栏sidebar里使用了一个叫selectInput的组件,它是一个下拉框,下拉框中是1000个会员的会员号,同时也支持直接输入会员号。本来想用一个直接输入会员号的组件,因为毕竟真实会员有几百上千万,下拉框其实是浪费的,但暂时还没有找到将输入的文本和dataList中元素对应起来的方法,如有朋友知道,请不吝赐教。
我们给这个selectInput组件起名为selection,组件上显示的文字是“请输入会员号”,可供选择的选择项必须是一个list,这里的as.list(names(dataList))就是把dataList中每个元素的名称(即会员号)组成一个list。
 
4
再来看server.R中的这一段:

  output$plot <- renderWordcloud2({
        getdata<-function(cid){
              dataList[[cid]]
        }
        word_color<-getdata(input$selection)
        wordcloud2(word_color$data, size=0.12, fontFamily = '微软雅黑', rotateRatio =0,
                       gridSize=15,  shuffle=F, color = word_color$colorVec )
      })

这一段代码是为了生成一个wordcloud2对象,使用的是wordcloud2包里专门用于shiny的函数renderWordcloud2。这个wordcloud2对象我们给它取了个名字叫plot,即第一行最开始的output$plot。要生成这个对象,我们先自定义了一个函数getdata, 用来得到一个指定会员的datacolorVec。随后生成一个叫word_color的list,getdata函数里的变量cid就是之前ui.R里的selectInput组件里的值,即input$selection(selection是我们自定义的selectInput组件的名字)。这一段代码也可以更简洁地写成:

 output$plot <- renderWordcloud2({
        wordcloud2(dataList[[input$selection]]$data, size=0.12, fontFamily = '微软雅黑', rotateRatio =0,
                       gridSize=15,  shuffle=F, color = dataList[[input$selection]]$colorVec )
      })

 
5
之后,让我们再回到ui.R中,看这一段代码:

 mainPanel(
      wordcloud2Output("plot")
    )

wordcloud2Output也是wordcloud2包里的一个专用于shiny的函数,用于将wordcloud2对象output出来。因此这一段很好理解,plot是我们先前在server.R中生成的wordcloud2对象,这里就是将这个对象output出来,放在mainPanel里。

至此,一个简单的制作用户标签的Shiny App就完成了。

你可能感兴趣的:(Shiny初试:用wordcould2画用户标签)