2016-09-27 59 views
0

我需要一些幫助來創建動態選項卡內部的動態圖。這是情況...我有一個包含數字營銷數據的數據文件。該文件包含以下幾條信息:廣告系列名稱,頻道名稱,網頁瀏覽量和訪問次數。廣告系列名稱是獨一無二的,並可彙總爲四種不同的營銷渠道之一。根據我提供的數據,這將在未來發生變化(例如,我可能會在下一個文件中使用六個營銷渠道),但這將用於故障排除目的。我想爲文件中的每個營銷渠道動態創建制表符和輸出。我已經能夠弄清楚如何創建這些標籤,但是我很難弄清楚如何創建其他類型的輸出(比如情節)以與每個標籤一起使用。在使用renderUI的條件選項卡中動態生成繪圖

output$mytabs = renderUI({ 
    if(is.null(rawData())){return()} 
    channels = unique(rawData()$Channel) 
    myTabs = lapply(channels, tabPanel) 
    do.call(tabsetPanel, myTabs) 
}) 

    output$scatterPlot <- renderUI({ 
    if(is.null(rawData())){return()} 
    createPlots() 
    myData = rawData() 
    channels = unique(myData$Channel) 
    plot_output_list <- lapply(seq_along(channels), function(i) { 
     plotname <- paste("plot", i, sep="") 
     plotOutput(plotname) 
    }) 

    do.call(tagList, plot_output_list) 
    }) 

    createPlots <- reactive ({ 
    myData = rawData() 
    channels = unique(myData$Channel) 
    for (i in seq_along(channels)) { 
     local({ 
     my_i <- i 
     plotname <- paste("plot", my_i, sep="") 
     tempRows = which(myData$Channel==channels[i]) 
     output[[plotname]] <- renderPlot({ 
      plot(x = myData$Spend[tempRows], y = myData$Return[tempRows]) 
     }) 
     }) 
    } 
    }) 

然後將這些UI中的文件中引用如下:

的接片在服務器上的文件下面的代碼使用renderUI創建

mainPanel(
    tabsetPanel(
     tabPanel("Data Summary", uiOutput("dataSummary")), 
     tabPanel("Parameters & Model Fit", 
       uiOutput('mytabs'), 
       uiOutput('scatterPlot')), 
     tabPanel("Budget & Spend Summary"), 
     tabPanel("Testing", plotOutput('plot5')) 
    ) 
) 

最後,我想在相應的營銷渠道標籤上爲每個營銷渠道繪製頁面瀏覽量和訪問量。目前,所有四個地塊都顯示在每個營銷渠道標籤中。在我的全局文件中,我創建了兩個函數 - 一個函數繪製一個通道,另一個函數繪製所有通道,並將每個通道作爲單獨的元素保存在列表中。我不確定哪一個最終會變得有用,如果有的話。

我確定我不理解如何設置'myTabs',或者我從ui中錯誤地引用它。即使有了這段代碼,這裏的某個人也許能夠迅速發現錯誤並推薦一個修復程序,但是我很樂意提供我的其他代碼,如果這會有所幫助的話。

謝謝! Jess

編輯:參考,這裏是我的所有代碼。只是將目標對象更改爲您想要工作的目錄。

library(shiny) 
dir = "" 
setwd(dir) 

####################### 
### Generate Data ### 
####################### 

channels = c("Affiliate","Email","Media","SEO") 
nObs = c(round(runif(1,100,200))) 
pageViews = runif(nObs*length(channels),50,500) 
visits = runif(nObs*length(channels),10,100) 

campaignNames = unlist(lapply(channels, FUN = function(x) paste(x,seq(from=1,to=nObs,by=1),sep=""))) 
channelNames = rep(channels,nObs) 

myData = data.frame(Campaign = campaignNames, Channel = channelNames, Return = pageViews, Spend = visits) 
write.table(myData,file="myTestData.csv",sep=",",col.names=TRUE,row.names=FALSE) 


######################## 
### Global Functions # 
######################## 

summarizeData = function(myDat){ 
    summaryData = summarize(group_by(myDat,Channel), 'Campaign Count' = length(Campaign), Return = sum(Return), Spend = sum(Spend)) 
    return(summaryData) 
} 


### PLOT DATA AND MODEL FIT ### 
plotSingle = function(myData, channelName){ 
    p1 <- ggplot(myData[which(myData$Channel==channelName),], aes(x = Spend, y = Return)) + 
    geom_point(color="black") + 
    theme(panel.background = element_rect(fill = 'grey85'), 
      panel.grid.major = element_line(colour = "white")) 
    return(p1) 
} 

plotAll = function(myData){ 
    channels = unique(myData$Channel) 
    plots <- list() # new empty list 
    for (i in 1:length(channels)) { 
    channelName = channels[i] 
    p1 = plotSingle(myData = myData, channelName = channelName) 
    plots[[i]] = p1 
    } 
    return(plots) 
} 


############ 
### UI ### 
############ 

ui <- fluidPage(
    headerPanel('Plot Testing'), 
    sidebarPanel(
    h3(helpText("Data Input")), 
    fileInput(inputId = "rawDataInput", label = "Upload Data"), 
    h5(helpText("Select the file parameters below")), 
    checkboxInput(inputId = 'header', label = 'Header', value = TRUE), 
    checkboxInput(inputId = "stringAsFactors", "stringAsFactors", FALSE), 
    br(), 
    radioButtons(inputId = 'sep', label = 'Separator', choices = c(Comma=',',Semicolon=';',Tab='\t', Space=''), selected = ',') 

), 
    mainPanel(
    tabsetPanel(
     tabPanel("Data Summary", uiOutput("dataSummary")), 
     tabPanel("Parameters & Model Fit", 
       uiOutput('mytabs'), 
       uiOutput('scatterPlot')), 
     tabPanel("Budget & Spend Summary"), 
     tabPanel("Testing", plotOutput('plot5')) 
    ) 
) 
) 

################ 
### Server ### 
################ 

server = function(input, output) { 

    rawData <- reactive({ 
    file1 <- input$rawDataInput 
    if(is.null(file1)){return()} 
    read.table(file=file1$datapath, sep=input$sep, header = input$header, stringsAsFactors = input$stringAsFactors) 

    }) 


    # this reactive output contains the summary of the dataset and display the summary in table format 
    output$filedf <- renderTable({ 
    if(is.null(rawData())){return()} 
    input$rawDataInput 
    }) 

    # this reactive output contains the summary of the dataset and display the summary in table format 
    output$sum <- renderTable({ 
    if(is.null(rawData())){return()} 
    summarizeData(rawData()) 
    }) 


    # This reactive output contains the dataset and display the dataset in table format 
    output$table <- renderTable({ 
    if(is.null(rawData())){return()} 
    rawData() 
    }) 

    dataPlots = reactive({ 
    channels = unique(rawData()$Channel) 
    plots = plotAll(rawData()) 
    }) 

    output$mytabs = renderUI({ 
    if(is.null(rawData())){return()} 
    channels = unique(rawData()$Channel) 
    createPlots() 
    plot_output_list <- lapply(seq_along(channels), function(i) { 
     plotname <- paste("plot", i, sep="") 
     plotOutput(plotname) 
    }) 
    myTabs = lapply(channels, tabPanel) 
    do.call(tabsetPanel, myTabs) 
    }) 

    createPlots <- reactive ({ 
    myData = rawData() 
    channels = unique(myData$Channel) 
    for (i in seq_along(channels)) { 
     local({ 
     my_i <- i 
     plotname <- paste("plot", my_i, sep="") 
     tempRows = which(myData$Channel==channels[i]) 
     output[[plotname]] <- renderPlot({ 
      plot(x = myData$Spend[tempRows], y = myData$Return[tempRows]) 
     }) 
     }) 
    } 
    }) 

    output$scatterPlot <- renderUI({ 
    if(is.null(rawData())){return()} 
    createPlots() 
    myData = rawData() 
    channels = unique(myData$Channel) 
    plot_output_list <- lapply(seq_along(channels), function(i) { 
     plotname <- paste("plot", i, sep="") 
     plotOutput(plotname) 
    }) 

    do.call(tagList, plot_output_list) 
    }) 

    output$dataSummary <- renderUI({ 
    if(is.null(rawData())){return()} 
    else 
     tabsetPanel(tabPanel("About file", tableOutput("filedf")),tabPanel("Data", tableOutput("table")),tabPanel("Summary", tableOutput("sum"))) 
    }) 

    output$plot5 = renderPlot({ 
    if(is.null(rawData())){return()} 
    myData = rawData() 
    channelName = "Affiliate" 
    p1 <- ggplot(myData[which(myData$Channel==channelName),], aes(x = Spend, y = Return)) + 
     geom_point(color="black") + 
     theme(panel.background = element_rect(fill = 'grey85'), 
      panel.grid.major = element_line(colour = "white")) 
    return(p1) 
    }) 

} 


### Run App ### 
shinyApp(ui = ui, server = server) 
+0

它更容易的奔跑來幫助你,當你提供一個最小[重複的例子(http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-例如)我們可以複製/粘貼到R運行。這應該包括樣本輸入數據。這樣可能的解決方案可以很容易地測試和驗證。 – MrFlick

+0

謝謝,@MrFlick。我擔心情況可能如此。我已將所有代碼添加到原始帖子中。 –

回答

0

您的示例並不完全最小化,因此我做了一些剝離。首先,數據和輔助功能

library(shiny) 
library(ggplot2) 

channels = c("Affiliate","Email","Media","SEO") 
nObs = c(round(runif(1,100,200))) 

myData = data.frame(
    Campaign = unlist(lapply(channels, FUN = function(x) paste(x,seq(from=1,to=nObs,by=1),sep=""))), 
    Channel = rep(channels,nObs), 
    Return = runif(nObs*length(channels),50,500), 
    Spend = runif(nObs*length(channels),10,100) 
) 

plotSingle = function(myData, channelName){ 
    ggplot(myData[which(myData$Channel==channelName),], aes(x = Spend, y = Return)) + 
    geom_point(color="black") + 
    theme(panel.background = element_rect(fill = 'grey85'), 
      panel.grid.major = element_line(colour = "white")) 
} 

現在UI

ui <- fluidPage(
    headerPanel('Plot Testing'), 
    mainPanel( 
    uiOutput('mytabs'), 
    plotOutput('scatterPlot') 
) 
) 

請注意,我們這裏只使用一個plotOutput。我們要做的只是根據當前選擇的選項卡更改它顯示的圖。這裏的服務器代碼

server = function(input, output) { 

    rawData <- reactive({ 
    myData 
    }) 

    output$mytabs = renderUI({ 
    if(is.null(rawData())){return()} 
    channels = unique(rawData()$Channel) 
    myTabs = unname(Map(tabPanel, channels)) 
    do.call(tabsetPanel, c(myTabs, id="channeltab")) 
    }) 

    output$scatterPlot <- renderPlot({ 
    if(is.null(rawData()) | is.null(input$channeltab)){return()} 
    plotSingle(rawData(), input$channeltab) 
    }) 

} 

你看,我們對我們創建了tabsetPanel設置id。然後,我們可以用input來確定哪個面板被選中並顯示正確的圖。所有與

shinyApp(ui = ui, server = server) 
+0

非常感謝!您的解決方案非常完美,實際上回答了我一直在努力的另一個問題! –

+0

太好了。如果解決方案解決了您的問題,請考慮單擊此答案旁邊的複選標記以將您的問題標記爲已回答 – MrFlick

+0

我還需要爲每個動態創建的選項卡生成其他內容(在這種情況下,我想添加四個sliderInput對象到每個選項卡)。你能幫我理解一些代碼,所以我可以概括你提供的解決方案嗎? –