首页 > 解决方案 > R Shiny Question --> Dynamicly Sort DataTable (Top/Bottom)

问题描述

我有一些锻炼数据,我正在尝试使用这些数据创建一个闪亮的仪表板。

以下是数据示例:

VisitNum VisitNumMonth Date       ClassLength Calories AvgHR Location Trainer
1        1             12/15/19   56          602      128   A        Mike
2        1             12/16/19   55          610      130   A        Mike
3        2             01/04/20   52          550      120   A        Sally
4        2             01/05/20   61          575      134   B        Jennie
5        2             01/10/20   57          654      133   A        Tim
6        2             01/17/20   55          592      119   A        Rachael
7        3             02/04/20   50          632      129   B        Jennie
8        3             02/22/20   48          630      125   B        Jennie
9        3             02/28/20   59          609      136   B        Marshall
10       4             03/03/20   53          598      134   A        Mike

我想获取这些数据并在 Shiny 仪表板中输出两个数据表。这两个数据表将包含该数据集中的列子集,其中一个表按卡路里燃烧排序,另一个表按 AvgHR 排序。但是,我希望有一个带有以下选项的 selectInput,“Top 5”和“Bottom 5”。我希望这些选择允许用户在使用 head() 和 tail() 函数之间来回切换。

这是我到目前为止所尝试的:

setwd("/location")
library(readxl)
mydata=as.data.frame(read_excel("mydata.xlsx",sheet=1))

library(RSQLite)
library(sqldf)
library(shiny)
library(shinydashboard)
library(DT)

topbotchoices=c("Top 5", "Bottom 5")


Table1=sqldf("select VisitNum as 'Visit #', Date, Location as 'Studio', Trainer, Calories, AvgHR
         from mydata
         group by VisitNum, Date, Location, Trainer")


ui <- fluidPage(
  titlePanel("Exercise Data Analysis"),
  dashboardPage(
    dashboardHeader(title=""),
    dashboardSidebar(
      sidebarMenu(
        menuItem("All Data",
                 tabName = "AllData",
                 icon=icon("table")
        ),
        menuItem("Top/Bottom",
                 tabName = "Topbottom",
                 icon=icon("sort")
        ),
        selectInput(inputId = "topbottomselect",label="Select Top 5 or Bottom 
5:",choices=topbotchoices,selected="Top 5")
      )
    ),
    dashboardBody(
      tabItems(
        tabItem(
          tabName = "AllData",
          DTOutput("alldata")
        ),
        tabItem(
          tabName = "Topbottom",
          DTOutput("topbottom1"),
          DTOutput("topbottom2")
      ))
    )
  )
)
# Define server logic 
server <- function(input, output) {
#----------ALL DATA TABLE----------#
  output$alldata=renderDT({

    datatable(Table1,options=list(pageLength=10,
                                  lengthMenu=c(2,5,8,10)
    ),rownames = FALSE)
  })


#---------TOP AND BOTTOM TABLES--------#


  TopRankData=reactive({

    ordered=head(Table1,n=5)


    return(ordered)
  })

BotRankData=reactive({

    ordered=tail(Table1,n=5)


    return(ordered)
  })



output$topbottom1=renderDT({

  datatable(TopRankData,rownames = FALSE,
            options = list(pageLength = 5, lengthChange = FALSE, dom='t'),
            caption = 'Top 5/Bottom 5 Classes by Calories Burned')

})

output$topbottom2=renderDT({

  datatable(BotRankData,rownames = FALSE,
            options = list(pageLength =5, lengthChange = FALSE, dom='t'),
            caption = "Top 5/Bottom 5 Classes by Avg HR")

})
  }


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

我不确定如何实现我想要的输出。任何帮助,将不胜感激。即使您认为我这样做完全荒谬 - 请让我知道我可以做得更好。谢谢!

标签: rsortingdynamicshiny

解决方案


一些想法:

  • 您的renderDTwithdatatable提供了一个不错的标题,内置箭头,用于从高到低排序(但仅针对当前显示的数字,在本例中为 5)。

  • 当您调用reactive数据的表达式时,您缺少括号,例如:TopRankData()

  • 我不确定,但我怀疑您希望前 5 个从最高到最低排序的最高 5 个(对于卡路里或平均 HR),对于后 5 个从最低到最高排序的最低 5 个。为此,您可以在查看设置后使用orderfor 。Table1input$topbottomselect

让我知道这是否是您的想法。

server <- function(input, output) {
  #----------ALL DATA TABLE----------#
  output$alldata=renderDT({
    datatable(Table1,options=list(pageLength=10,
                                  lengthMenu=c(2,5,8,10)
    ),rownames = FALSE)
  })

  #---------TOP AND BOTTOM TABLES--------#
  TopRankData=reactive({
    if (input$topbottomselect == "Top 5") {
      ordered=head(Table1[order(-Table1$Calories), ],n=5)
    } else {
      ordered=head(Table1[order(Table1$Calories), ],n=5)
    }
    return(ordered)
  })

  BotRankData=reactive({
    if (input$topbottomselect == "Top 5") {
      ordered=head(Table1[order(-Table1$AvgHR), ],n=5)
    } else {
      ordered=head(Table1[order(Table1$AvgHR), ],n=5)
    }
    return(ordered)
  })

  output$topbottom1=renderDT({
    datatable(TopRankData(),rownames = FALSE,
              options = list(pageLength = 5, lengthChange = FALSE, dom='t'),
              caption = 'Top 5/Bottom 5 Classes by Calories Burned')
  })

  output$topbottom2=renderDT({
    datatable(BotRankData(),rownames = FALSE,
              options = list(pageLength =5, lengthChange = FALSE, dom='t'),
              caption = "Top 5/Bottom 5 Classes by Avg HR")
  })
}

推荐阅读