Shiny初试:用wordcould2画用户标签

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

用户画像示例

教程看的是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就完成了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • 作品概述 这个作品刚刚获得“中国电科杯”城市数据创新大赛的城市交通专项奖,现在作为案例分享出来供同行交流讨论。虚的...
    真依然很拉风阅读 8,673评论 2 19
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,463评论 25 707
  • 今天我读了《动物特战队之深海危机》第17页到32页。 好词:当之无愧。热血沸腾。斗志昂扬。威风十足。不约而同。情不...
    owen彦睿阅读 371评论 0 0
  • 因为一些原因,我在京城待了十天,花了九天时间去丈量这座城市,依旧感觉远远不够。 这是座对单车很宽容的城市。 而共享...
    柒晓晓阅读 344评论 2 2