如何将R脚本转换为Shiny应用程序?

时间:2018-06-22 11:33:08

标签: r shiny

我真的很想将我的一些脚本转移到R Shiny环境中,供我(未经R语言培训的)同事在我不在的情况下使用。

我特别想上传一个脚本,它分为三个部分:

  • 导入数据
  • 重组数据
  • 可视化结果

我不知道从构建代码/将代码转换为Shiny应用程序的起点,但是我的想法是用户先上传一个.csv文件(格式始终相同),然后再上传该应用程序着手重组数据,然后提供可视化效果。

我在网上看过教程,但是似乎都没有涵盖我在这里想要做的事情。

一些有关如何实现这一目标的指导将是很棒的。

样本数据集:

structure(list(date = structure(c(17683, 17683, 17683, 17683, 
17684, 17684, 17684, 17685, 17686, 17686, 17687, 17687, 17687, 
17687, 17688, 17689, 17689, 17689, 17689), class = "Date"), type = c("Completed", 
"Completed", "Completed", "Missed", "Completed", "Completed", 
"Missed", "Completed", "Completed", "Missed", "Completed", "Completed", 
"Completed", "Missed", "Completed", "Completed", "Completed", 
"Completed", "Missed"), retailer_code = c("GGdwO3HFDV", "Tj8vwJvyH1", 
"npqPjZyMy5", "GGdwO3HFDV", "npqPjZyMy5", "GGdwO3HFDV", "npqPjZyMy5", 
"npqPjZyMy5", "npqPjZyMy5", "npqPjZyMy5", "1mRdYODJBH", "Tj8vwJvyH1", 
"npqPjZyMy5", "npqPjZyMy5", "Tj8vwJvyH1", "Tj8vwJvyH1", "npqPjZyMy5", 
"HbNaIqdedB", "npqPjZyMy5"), count = c(2L, 1L, 1L, 3L, 4L, 1L, 
1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 4L, 2L, 1L, 1L)), class = "data.frame", row.names = c(NA, 
-19L))

我的代码:

library(dplyr); library(tidyr); library(ggplot2)

# Read in data
eu_chats <- read.csv("20180601_20180607_EU.csv", sep = ",", stringsAsFactors = FALSE)

# Rename columns
colnames(eu_chats) <- c("date", "type", "retailer_code", "count")

# Remove time from date column
eu_chats$date <- gsub(", 00:00:00.000", "", eu_chats$date)
eu_chats$date <- gsub("st", "", eu_chats$date)
eu_chats$date <- gsub("nd", "", eu_chats$date)
eu_chats$date <- gsub("rd", "", eu_chats$date)
eu_chats$date <- gsub("th", "", eu_chats$date)

eu_chats$date <- as.Date(eu_chats$date, format='%B %d %Y')

# Label missed anc completed chats accordingly
eu_chats$type[eu_chats$type == "conversation-auto-archived"] <- "Missed"
eu_chats$type[eu_chats$type == "conversation-archived"] <- "Completed"

# Add new columns (intialise to 0 or "retailer")
eu_chats$retailer <- ""

# Identify France, Germany & UK stores
eu_chats$retailer[eu_chats$retailer_code == "npqPjZyMy5"] <- "Retailer1"
eu_chats$retailer[eu_chats$retailer_code == "HbNaIqdedB"] <- "Retailer2"
eu_chats$retailer[eu_chats$retailer_code == "1mRdYODJBH"] <- "Retailer3"
eu_chats$retailer[eu_chats$retailer_code == "GGdwO3HFDV"] <- "Retailer4"
eu_chats$retailer[eu_chats$retailer_code == "Tj8vwJvyH1"] <- "Retailer5"
eu_chats$retailer_code <- NULL

# Visualise chats

eu_chats %>%
  spread(type, count, fill = 0) %>%   # Spread the count column in missed and completed
  mutate(Total = Completed + Missed) %>%   # Create the Total column
  ggplot(aes(as.Date(date, tz = "Europe/London"), Total)) + 
  geom_col(aes(fill = "Total"),
           colour = "black", width = 0.75) + # total bar (with stat = "identity")
  geom_col(aes(y = Missed, fill = "Missed"),
           colour = "black", width = 0.75) + # missed bar
  geom_text(aes(label = paste("Total chats:", Total)), # add total label
            hjust = -0.05, vjust = 0.7, size = 3.5) + 
  geom_text(aes(label = paste("Missed chats:", Missed, "(", round(Missed/Total*100, 2), "%)")), # add missed label and calculate percentage
            hjust = -0.05, vjust = -0.7, size = 3.5, colour = "red") + 
  scale_fill_manual(name = "",  # Manual fill scale
                    values = c("Total" = "forestgreen", "Missed" = "red")) +
  facet_grid(retailer~.) +  # Displayed per retailer
  scale_y_continuous(limits = c(0, max(eu_chats$count) * 2)) + # Make labels visible
  scale_x_date(date_breaks = "1 day", name = "Date") +
  ggtitle(paste("Missed Chats (", min(eu_chats$date), "-", max(eu_chats$date), ")")) +
  coord_flip()

1 个答案:

答案 0 :(得分:2)

由于您没有提供csv文件,所以我没有测试以下代码。但这应该是一个开始,尽管有几种方法可以实现所需的行为。

  • 我正在reactive对象中进行导入和重组

  • 可视化位于renderPlot内。

我没有在代码中使用fileInput,而是从您的dput输出中获取了硬编码的数据。如果要改用fileInput,请取消注释反应式顶部的两行(其在代码中也已注释)。

日期格式仍然为我提供NA值。

因此我将格式从'%B %d %Y'更改为"%Y-%m-%d"

library(dplyr); library(tidyr); library(ggplot2)
library(shiny)

data = structure(list(date = structure(c(17683, 17683, 17683, 17683, 
                                         17684, 17684, 17684, 17685, 17686, 17686, 17687, 17687, 17687, 
                                         17687, 17688, 17689, 17689, 17689, 17689), class = "Date"), type = c("Completed", 
                                                                                                              "Completed", "Completed", "Missed", "Completed", "Completed", 
                                                                                                              "Missed", "Completed", "Completed", "Missed", "Completed", "Completed", 
                                                                                                              "Completed", "Missed", "Completed", "Completed", "Completed", 
                                                                                                              "Completed", "Missed"), retailer_code = c("GGdwO3HFDV", "Tj8vwJvyH1", 
                                                                                                                                                        "npqPjZyMy5", "GGdwO3HFDV", "npqPjZyMy5", "GGdwO3HFDV", "npqPjZyMy5", 
                                                                                                                                                        "npqPjZyMy5", "npqPjZyMy5", "npqPjZyMy5", "1mRdYODJBH", "Tj8vwJvyH1", 
                                                                                                                                                        "npqPjZyMy5", "npqPjZyMy5", "Tj8vwJvyH1", "Tj8vwJvyH1", "npqPjZyMy5", 
                                                                                                                                                        "HbNaIqdedB", "npqPjZyMy5"), count = c(2L, 1L, 1L, 3L, 4L, 1L, 
                                                                                                                                                                                               1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 4L, 2L, 1L, 1L)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                                                                                                                         -19L))


ui <- fluidPage(
  fileInput("inFile", "Upload a csv-file"),
  selectInput("header", label = "Set header to TRUE or FALSE", choices = c(TRUE, FALSE)),
  plotOutput("plot")
)

server <- function(input, output) {

  eu_chats_react <- reactive({

    ## Uncomment the following 2 lines when using the fileInput!!
    # req(input$inFile$datapath)
    # eu_chats <- read.csv(input$inFile$datapath, header = as.logical(input$header))

    eu_chats <- data

    # Rename columns
    colnames(eu_chats) <- c("date", "type", "retailer_code", "count")

    # Remove time from date column
    eu_chats$date <- gsub(", 00:00:00.000", "", eu_chats$date)
    eu_chats$date <- gsub("st", "", eu_chats$date)
    eu_chats$date <- gsub("nd", "", eu_chats$date)
    eu_chats$date <- gsub("rd", "", eu_chats$date)
    eu_chats$date <- gsub("th", "", eu_chats$date)


    ## Other Date Format !!!!
    # eu_chats$date <- as.Date(eu_chats$date, format='%B %d %Y')
    eu_chats$date <- as.Date(eu_chats$date, format="%Y-%m-%d")

    # Label missed anc completed chats accordingly
    eu_chats$type[eu_chats$type == "conversation-auto-archived"] <- "Missed"
    eu_chats$type[eu_chats$type == "conversation-archived"] <- "Completed"

    # Add new columns (intialise to 0 or "retailer")
    eu_chats$retailer <- ""

    # Identify France, Germany & UK stores
    eu_chats$retailer[eu_chats$retailer_code == "npqPjZyMy5"] <- "Retailer1"
    eu_chats$retailer[eu_chats$retailer_code == "HbNaIqdedB"] <- "Retailer2"
    eu_chats$retailer[eu_chats$retailer_code == "1mRdYODJBH"] <- "Retailer3"
    eu_chats$retailer[eu_chats$retailer_code == "GGdwO3HFDV"] <- "Retailer4"
    eu_chats$retailer[eu_chats$retailer_code == "Tj8vwJvyH1"] <- "Retailer5"
    eu_chats$retailer_code <- NULL

    eu_chats
  })

  output$plot <- renderPlot({
    eu_chats_react() %>%
      spread(type, count, fill = 0) %>%   # Spread the count column in missed and completed
      mutate(Total = Completed + Missed) %>%   # Create the Total column
      ggplot(aes(as.Date(date, tz = "Europe/London"), Total)) + 
      geom_col(aes(fill = "Total"),
               colour = "black", width = 0.75) + # total bar (with stat = "identity")
      geom_col(aes(y = Missed, fill = "Missed"),
               colour = "black", width = 0.75) + # missed bar
      geom_text(aes(label = paste("Total chats:", Total)), # add total label
                hjust = -0.05, vjust = 0.7, size = 3.5) + 
      geom_text(aes(label = paste("Missed chats:", Missed, "(", round(Missed/Total*100, 2), "%)")), # add missed label and calculate percentage
                hjust = -0.05, vjust = -0.7, size = 3.5, colour = "red") + 
      scale_fill_manual(name = "",  # Manual fill scale
                        values = c("Total" = "forestgreen", "Missed" = "red")) +
      facet_grid(retailer~.) +  # Displayed per retailer
      scale_y_continuous(limits = c(0, max(eu_chats_react()$count) * 2)) + # Make labels visible
      scale_x_date(date_breaks = "1 day", name = "Date") +
      ggtitle(paste("Missed Chats (", min(eu_chats_react()$date), "-", max(eu_chats_react()$date), ")")) +
      coord_flip()
  })
}

shinyApp(ui, server)

使用软件包shinyBS,您可以将绘图放置为模态,但不能调整大小,您可能需要查看shinyjqui或任何交互式绘图库(绘图,highcharter,RCharts等) ..)

但是对您来说可能就好了,只需添加library(shinyBS)并将ui功能交换到:

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      fileInput("inFile", "Upload a csv-file"),
      selectInput("header", label = "Set header to TRUE or FALSE", choices = c(TRUE, FALSE)),
      actionButton("go", "Go")
                 ),
    mainPanel(
      bsModal("modalExample", "Your plot", "go", size = "large",plotOutput("plot"))
    )
  )
)