动态过滤器,在ggvis中添加图例并绘制离散X轴

时间:2016-09-24 06:20:23

标签: r plot shiny shiny-server

我是RShiny的新人,但在R中有一点经验。我刚刚开始研究R闪亮并试图在X轴上准备一个简单的两个数量线图与周。由于它更具代表性,我使用了csv上传功能并动态选择要在UI上填充的值。 我使用的示例CSV数据如下:

year-week   Group   big small   Time
1415          G1    10     5    1
1416          G1    20     6    2
1429          G1    15     4    3
1530          G1    17     5    4
1535          G1    20     7    5
1601          G1    13     6    6
1606          G1    12     5    7
1410          G2    9      3    1
1415          G2    11     4    2
1439          G2    13     5    3
1529          G2    15     6    4
1531          G2    15     4    5
1610          G2    12     5    6
1615          G2    19     6    7
1412          G3    9     10    1
1417          G3    20     6    2
1452          G3    13     5    3
1501          G3    10     4    4
1530          G3    17     7    5
1620          G3    16     5    6

我的主要目标是:

1)选择一个CSV并上传(它正常工作)

2)在x轴上进行一周(这是一个小小的工作。由于我有一周的年份,它的离散值如1415,这意味着2014,15周,然后是1420,这意味着相同第20周,然后是1515,即2015年,第15周等等。我想按原样绘制,但在x轴上,它绘制了一个连续的周数。所以,作为一个解决方案,我刚刚制作连续几周的列作为时间。非常感谢任何关于如何使用年周列而不是X轴上的连续函数的提示。)

3)选择两个动态轴,然后将它们绘制为Y轴上的折线图,颜色不同(工作正常)

4)为Y上添加的两条线添加标签。(它不起作用。由于两条绘制的线不是因子的一部分,而是两个不同的列动态选择,我无法绘制图例来解释哪一种颜色对应哪一行。需要帮助。)

5)然后最后一部分是我想要为组号包含一个动态过滤器。 (它不能正常工作并需要帮助) 我尝试将选择输入下拉到UI但不确定如何将其映射到server.R中选定的CSV文件 。我不能直接输入值,因为有100个行对应一个组,并且有多个组。 但是,我知道只有一列需要过滤器,只有该列的过滤器才能显示折线图,但对于如何输入该部分只是很少混淆。我已经浏览了很多文章和问题,但没有得到其他领域动态选择的类似情况。

以下是代码,它正在为一个小组工作,尽管每周工作周的工作顺序,因为一周只有52周,它处理1452年和1452年之间的差距。 1501。 所以我需要有关图例部分和代码的帮助来过滤组,以便它可以一起运行所有数据。

以下是我迄今为止所使用的代码:

UI.R

library(ggvis)
library(shiny)
shinyUI(pageWithSidebar(
  div(),
  sidebarPanel(
    fileInput('datfile', ''),
    selectInput('x', 'x:' ,'x'),
    selectInput('y', 'y:', 'y'),
    selectInput('z', 'z:', 'z'),
    ######### Need to choose one of the following 2 methods for filtering ########
    #1#
    #selectInput("w", label = h3("Filter group"),
    #            ("Group" = "Group"),selected = "Group"),
    ############################## OR ###################################             
    # 2# To make a select box 
    selectInput("select", label = h3("Filter Group"), 
               choices = list("G1" = 1, "G2" = 2, "G3" = 3), 
                selected = 1),
    ######################################################################
    hr(),
    fluidRow(column(3, verbatimTextOutput("value"))),
    uiOutput("plot_ui")

  ),
  mainPanel(
    ggvisOutput("plot")
  )
))

Server.R

library(shiny)
library(dplyr)
library(ggvis)

shinyServer(function(input, output, session) {
  #load the data when the user inputs a file
  theData <- reactive({
    infile <- input$datfile        
    if(is.null(infile))
      return(NULL)        
    d <- read.csv(infile$datapath, header = T)
    d        
  })

  # dynamic variable names
  observe({
    data<-theData()
    updateSelectInput(session, 'x', choices = names(data))
    updateSelectInput(session, 'y', choices = names(data))
    updateSelectInput(session, 'z', choices = names(data))
  }) # end observe

  #gets the y variable name, will be used to change the plot legends
  yVarName<-reactive({
    input$y
  })

  #gets the x variable name, will be used to change the plot legends
  xVarName<-reactive({
    input$x
  })

  #gets the z variable name, will be used to change the plot legends
  zVarName<-reactive({
    input$z
  })

  #make the filteredData frame

  filteredData<-reactive({
    data<-isolate(theData())
    #if there is no input, make a dummy dataframe
    if(input$x=="x" && input$y=="y" && input$z=="z"){
      if(is.null(data)){
        data<-data.frame(x=0,y=0,z=0)
      }
    }else{
      data<-data[,c(input$x,input$y,input$z)]    # Here data shall be filtered   
      names(data)<-c("x","y","z")
    }
    data
  })

  #plot the ggvis plot in a reactive block so that it changes with filteredData
  vis<-reactive({
    plotData<-filteredData()

    plotData %>%
      ggvis(~x, ~y) %>%
      #ggvis(~x, ~y, storke = c(~y,~z)) %>%   # It's not working & not picking y&z together
      #set_options(duration=0) %>%
      layer_paths(stroke := "darkblue", fill := NA) %>%
      layer_paths(x = ~x, y = ~z, stroke := "orangered", fill := NA) %>%
      add_axis("y", title = "Big v/s small") %>%
      add_axis("x", title = xVarName()) %>%
      #add_legend('stroke', orient="left") %>%   # Unable to put the legend
      add_tooltip(function(df) format(sqrt(df$x),digits=2))
  })
  vis%>%bind_shiny("plot", "plot_ui")

})

非常感谢任何帮助。它可能不是那么艰难,我通过使用dplyr作为子集和过滤器在R中做了类似的部分,但不知道如何在这里映射相同的部分。如果上述任何内容不清楚或需要更多信息,请告诉我。 如果通过直接加载CVS或使用ggvis的情节更好地解决方案,那么我也可以更改代码片段但是想达到我的目标。

1 个答案:

答案 0 :(得分:1)

<强> UI.R

library(ggvis)
library(shiny)
shinyUI( fluidPage ( (img(src="picture.jpg")),
  theme = "bootstrap.css",
  fluidRow( 
    #headerPanel(title=div(img(src="picture.jpg"))),
      column(9, align="center", offset = 2,
           textInput("string", label="",value = "Big V/s Small"),
           tags$style(type="text/css", "#string { height: 50px; width: 100%; text-align:center; font-size: 26px;}")
    )
  ),
  pageWithSidebar(
    div(),
    sidebarPanel(
      fileInput('datfile', ''),
      selectInput('x', 'x:' ,'x'),
      selectInput('y', 'y:', 'y'),
      selectInput('z', 'z:', 'z'),
      ################ Need to choose one of the following method for filtering ############
      # To make a select box 
      selectInput("w", label = h3("Filter Group"), 
                  choices = list()),
      ######################################################################
      hr(),
      fluidRow(column(3, verbatimTextOutput("value"))),
      uiOutput("plot_ui")

    ),
    mainPanel(
      ggvisOutput("plot")
    )
  ))
)

<强> Sevrer.R

#install.packages('rsconnect')
#install.packages('bitops')
library(shiny)
library(dplyr)
library(ggvis)
library(reshape2)

shinyServer(function(input, output, session) {
  #load the data when the user inputs a file
  theData <- reactive({
    infile <- input$datfile
    if (is.null(infile))
      return(NULL)
    d <-
      read.csv(infile$datapath,
               header = T,
               stringsAsFactors = FALSE)
    d
  })

  # dynamic variable names
  observe({
    data <- theData()
    updateSelectInput(session, 'x', choices = names(data))
    updateSelectInput(session, 'y', choices = names(data))
    updateSelectInput(session, 'z', choices = names(data))
    updateSelectInput(session, 'w', choices = unique(data$group))
  }) # end observe

  #gets the y variable name, will be used to change the plot legends
  yVarName <- reactive({
    input$y
  })

  #gets the x variable name, will be used to change the plot legends
  xVarName <- reactive({
    input$x
  })

  #gets the z variable name, will be used to change the plot legends
  zVarName <- reactive({
    input$z
  })

  #gets the w variable name, will be used to change the plot legends
  wVarName <- reactive({
    input$w
  })

  #make the filteredData frame

  filteredData <- reactive({
    data <- isolate(theData())
    #if there is no input, make a dummy dataframe
    if (input$x == "x" && input$y == "y" && input$z == "z") {
      if (is.null(data)) {
        data <- data.frame(x = 0, y = 0, z = 0)
      }
    } else{
      data = data[which(data$fineline_nbr == input$w), ]
      data <- data[, c(input$x, input$y, input$z)]
      names(data) <- c('x', input$y, input$z)
    }
    data
  })

  #plot the ggvis plot in a reactive block so that it changes with filteredData
  vis <- reactive({
    plotData <- filteredData()
    plotData <- melt(plotData, id.vars = c('x'))
    print(names(plotData))
    plotData %>% ggvis(x =  ~ x,
                       y =  ~ value,
                       stroke =  ~ variable) %>% layer_lines()
  })
  vis %>% bind_shiny("plot", "plot_ui")
})