Форматирование чисел в блестящей таблице

Aug 27 2020

Я создаю приложение для визуализации некоторых данных, но с трудом могу получить таблицу в нужном мне формате. Вот мой код:

library(shiny)
library (RCurl)
library(zoo)
library(ggplot2)
library(DT)
library(shinythemes)
library(tidyverse)

Sys.setlocale("LC_TIME", "C")

gear_volume <- read.csv("https://data.mendeley.com/datasets/gpynbmn7f9/1/files/63b5c005-ff83-4dfc-bf4b-87e353b5310d/gear_volume.csv?dl=1", sep = "\t") %>%
  mutate(date = as.yearmon(paste(date),"%b %Y"),
         volume = as.numeric(volume)/10^6,
         variable = "Gear",
         unit = "Catch (million t)") %>%
  rename(quantity = volume)

gear_number <- read.csv("https://data.mendeley.com/datasets/gpynbmn7f9/1/files/789a7b5d-4ade-4913-a1c6-2f33136d33c0/gear_number.csv?dl=1", sep = "\t") %>%
  mutate(date = as.yearmon(paste(date),"%b %Y"),
         count = as.numeric(count),
         variable = "Gear",
         unit = "Number of fisheries") %>%
  rename(quantity = count)

gear <- gear <- rbind(gear_volume, gear_number) %>%
  mutate(date = as.yearmon(paste(date),"%b %Y"))

rm(gear_volume, gear_number)

colors <- c("#B8B9BC", "#0A1D27", "#034149", "#06907B")

##Create plot theme
plot_theme <- theme(legend.position = "none",
                    legend.title = element_blank(),
                    axis.line.x =  element_line(color = "black", size = 0.25),
                    axis.line.y = element_line(color = "black", size = 0.25),
                    axis.ticks = element_line(color = "black", size = 0.25),
                    panel.grid.major = element_blank(),
                    panel.grid.minor = element_blank(),
                    panel.border = element_blank(),
                    panel.background = element_blank(),
                    axis.title.x = element_blank(),
                    axis.text.x = element_text(family = "Arial",size = 11, colour = "black"),
                    axis.title.y = element_text(family = "Arial",size = 12, face = "bold", colour = "black"),
                    axis.text.y = element_text(family = "Arial",size = 11, colour = "black"),
                    plot.margin = unit(c(2,2,2,4),"mm"))

# Define UI for application that draws a stacked area chart + table
ui <- fluidPage(theme = shinytheme("simplex"),
   
   # Application title
   titlePanel("What does the Marine Stewardship Council (MSC) ecolabel certify?"),
   
   # Sidebar with a slider input for number of bins 
   fluidRow(
     column(4,
            selectInput("fishery_unit", label = h4("Display data as:"), 
                        unique(as.character(gear$unit))) ), column(4, sliderInput("date", label = h4("Select time range:"), 2000, 2018, value = c(2000, 2018), step = 1, sep = "") ) ), # Create a new row for the table. tabsetPanel( tabPanel("Graphical view", plotOutput("distPlot")), tabPanel("Data", dataTableOutput("distTable"))) ) # Define server logic required to draw a stacked area chart server <- function(input, output) { dataInput <- reactive({ gear[gear$unit==input$fishery_unit,] }) output$distPlot <- renderPlot({
     ggplot(dataInput(), aes(x = date, y = quantity, fill = gear)) +
       geom_area(position = "stack") +
       xlab("") + ylab("Allocation by gear") +
       scale_fill_manual(values = colors) +
       plot_theme +
       scale_x_continuous(limits = input$date, expand = c(0, 0)) + scale_y_continuous(expand = c(0, 0)) }) output$distTable <- renderDataTable({
    dataInput()
  },
  extensions = "Buttons",
  options = list(
    scrollY = "300px", pageLength = 10, scrollX = TRUE, dom = "Bftsp",
    buttons = c("copy", "csv", "excel"))
  )
}
                                    
                                    
# Run the application 
shinyApp(ui = ui, server = server)

Моя проблема двоякая:

1. Формат даты

На Dataвкладке я бы хотел, чтобы дата отображалась как yearmonдата вместо десятичной. Я не уверен, почему он отображается так, учитывая, что gear$dateон отформатирован как yearmon. Есть идеи, как это решить?

2. Числовой формат

Я пытался округлить quantityтак, чтобы отображалась только одна или две цифры, например, используя formatRound(3, 2)в разных местах моей renderDataTable()команды, но это не сработало ... Есть идеи? Кроме того, есть ли способ заменить quantityимя столбца выбранным входом, т.е. Number of fisheriesили, Catch (million t)а затем удалить unitстолбец?

Большое спасибо за вашу помощь. Жду ваших идей :)

Ответы

1 stefan Aug 27 2020 at 01:41
  1. Проблема с вашим date, вероятно, заключается в том, что класс yearmon(который, насколько я понял из документов, является числовым) не поддерживается DT(но просто догадывается) и отображается как числовой. Чтобы предотвратить это, вы можете сохранить исходный dateсимвол var и добавить второй помощник date1для построения графика, который удаляется перед визуализацией таблицы. Кстати: я делаю преобразование yearmonтолько один раз после rbind.

  2. Вторая проблема (и) более сложная, но ее можно решить следующим образом:

    output$distTable <- renderDataTable({ dataInput() %>% # Rename 'quantity' to 'input$fishery_unit' using tidy evaluation
          rename(!!sym(input$fishery_unit) := quantity) %>% # Drop 'unit' and helper 'date1' columns select(-unit, -date1) %>% # Convert to DT::datatable DT::datatable(extensions = "Buttons", options = list( scrollY = "300px", pageLength = 10, scrollX = TRUE, dom = "Bftsp", buttons = c("copy", "csv", "excel") )) %>% # Format the former quantity column, which we renamed to input$fishery_unit
          formatRound(input$fishery_unit, 1)
      })
    

Для справки - полный воспроизводимый код:

library(shiny)
library (RCurl)
library(zoo)
library(ggplot2)
library(DT)
library(shinythemes)
library(tidyverse)

Sys.setlocale("LC_TIME", "C")

gear_volume <- read.csv("https://data.mendeley.com/datasets/gpynbmn7f9/1/files/63b5c005-ff83-4dfc-bf4b-87e353b5310d/gear_volume.csv?dl=1", sep = "\t") %>%
  mutate(volume = as.numeric(volume)/10^6,
         variable = "Gear",
         unit = "Catch (million t)") %>%
  rename(quantity = volume)

gear_number <- read.csv("https://data.mendeley.com/datasets/gpynbmn7f9/1/files/789a7b5d-4ade-4913-a1c6-2f33136d33c0/gear_number.csv?dl=1", sep = "\t") %>%
  mutate(count = as.numeric(count),
         variable = "Gear",
         unit = "Number of fisheries") %>%
  rename(quantity = count)

gear <- gear <- rbind(gear_volume, gear_number) %>%  
  # Add helper "date1" 
  mutate(date1 = as.yearmon(paste(date),"%b %Y"))

rm(gear_volume, gear_number)

colors <- c("#B8B9BC", "#0A1D27", "#034149", "#06907B")

##Create plot theme
plot_theme <- theme(legend.position = "none",
                    legend.title = element_blank(),
                    axis.line.x =  element_line(color = "black", size = 0.25),
                    axis.line.y = element_line(color = "black", size = 0.25),
                    axis.ticks = element_line(color = "black", size = 0.25),
                    panel.grid.major = element_blank(),
                    panel.grid.minor = element_blank(),
                    panel.border = element_blank(),
                    panel.background = element_blank(),
                    axis.title.x = element_blank(),
                    axis.text.x = element_text(family = "Arial",size = 11, colour = "black"),
                    axis.title.y = element_text(family = "Arial",size = 12, face = "bold", colour = "black"),
                    axis.text.y = element_text(family = "Arial",size = 11, colour = "black"),
                    plot.margin = unit(c(2,2,2,4),"mm"))

# Define UI for application that draws a stacked area chart + table
ui <- fluidPage(theme = shinytheme("simplex"),
                
                # Application title
                titlePanel("What does the Marine Stewardship Council (MSC) ecolabel certify?"),
                
                # Sidebar with a slider input for number of bins 
                fluidRow(
                  column(4,
                         selectInput("fishery_unit", label = h4("Display data as:"), 
                                     unique(as.character(gear$unit)))
                  ),
                  column(4,
                         sliderInput("date", label = h4("Select time range:"),
                                     2000, 2018, value = c(2000, 2018), step = 1, sep = "")
                  )
                ),
                # Create a new row for the table.
                tabsetPanel(
                  tabPanel("Graphical view", plotOutput("distPlot")),
                  tabPanel("Data", dataTableOutput("distTable")))
)

# Define server logic required to draw a stacked area chart
server <- function(input, output) {
  dataInput <- reactive({
    gear[gear$unit==input$fishery_unit,]
  })
  output$distPlot <- renderPlot({ # Use "date1" for plotting ggplot(dataInput(), aes(x = date1, y = quantity, fill = gear)) + geom_area(position = "stack") + xlab("") + ylab("Allocation by gear") + scale_fill_manual(values = colors) + plot_theme + scale_x_continuous(limits = input$date, expand = c(0, 0)) +
      scale_y_continuous(expand = c(0, 0))
  })
  output$distTable <- renderDataTable({ dataInput() %>% rename(!!sym(input$fishery_unit) := quantity) %>% 
      select(-unit, -date1) %>% 
      DT::datatable(extensions = "Buttons",
                    options = list(
                      scrollY = "300px", pageLength = 10, scrollX = TRUE, dom = "Bftsp",
                      buttons = c("copy", "csv", "excel")
                    )) %>% 
      formatRound(input$fishery_unit, 1)
  })
}

# Run the application 
shinyApp(ui = ui, server = server)