Is it possible to program a dashboard with the same functionality as in this example, but instead of using reactable, using the DT
(DataTable) package?
Requirement: Jump to Table 2 for showing detailed information after click in Table 1. The counting of totals in the footer as shown in the above mentioned question is not necessary.
Are there any comparative studies on which package is better suited for displaying large datasets?
This is an example without the functionality for which I am asking.
library(shiny)
library(shinydashboard)
library(DT)
d1 <- data.frame(
name = c("Frank", "Emma", "Kurt", "Johanna", "Anna", "Ben", "Chris", "David", "Eva", "Felix", "Gina", "Hannah", "Iris", "Jack", "Karen", "Leo", "Mia", "Nina", "Omar", "Paul"),
team = c("A", "A", "B", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B"),
score = c(12, 15, 13, 13, 14, 11, 10, 16, 9, 8, 17, 14, 12, 13, 15, 16, 11, 10, 9, 8)
)
d2 <- data.frame(
name = c(
"Frank", "Frank", "Frank",
"Emma", "Emma", "Emma",
"Kurt", "Kurt", "Kurt",
"Johanna", "Johanna", "Johanna",
"Anna", "Anna", "Anna",
"Ben", "Ben", "Ben",
"Chris", "Chris", "Chris",
"David", "David", "David",
"Eva", "Eva", "Eva",
"Felix", "Felix", "Felix",
"Gina", "Gina", "Gina",
"Hannah", "Hannah", "Hannah",
"Iris", "Iris", "Iris",
"Jack", "Jack", "Jack",
"Karen", "Karen", "Karen",
"Leo", "Leo", "Leo",
"Mia", "Mia", "Mia",
"Nina", "Nina", "Nina",
"Omar", "Omar", "Omar",
"Paul", "Paul", "Paul"
),
match = c(
1, 2, 3, # Frank
1, 2, 3, # Emma
1, 2, 3, # Kurt
1, 2, 3, # Johanna
1, 2, 3, # Anna
1, 2, 3, # Ben
1, 2, 3, # Chris
1, 2, 3, # David
1, 2, 3, # Eva
1, 2, 3, # Felix
1, 2, 3, # Gina
1, 2, 3, # Hannah
1, 2, 3, # Iris
1, 2, 3, # Jack
1, 2, 3, # Karen
1, 2, 3, # Leo
1, 2, 3, # Mia
1, 2, 3, # Nina
1, 2, 3, # Omar
1, 2, 3 # Paul
),
score = c(
4, 4, 4, # Frank (12)
5, 5, 5, # Emma (15)
4, 4, 5, # Kurt (13)
4, 4, 5, # Johanna (13)
5, 4, 5, # Anna (14)
4, 4, 3, # Ben (11)
4, 3, 3, # Chris (10)
6, 5, 5, # David (16)
3, 3, 3, # Eva (9)
3, 3, 2, # Felix (8)
6, 6, 5, # Gina (17)
5, 5, 4, # Hannah (14)
4, 4, 4, # Iris (12)
4, 4, 5, # Jack (13)
5, 5, 5, # Karen (15)
6, 5, 5, # Leo (16)
4, 4, 3, # Mia (11)
4, 3, 3, # Nina (10)
3, 3, 3, # Omar (9)
3, 3, 2 # Paul (8)
)
)
ui <- dashboardPage(
dashboardHeader(title = "Test"),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Table 1", tabName = "table1", icon = icon("table")),
menuItem("Table 2", tabName = "table2", icon = icon("table"))
)
),
dashboardBody(
tabItems(
tabItem(tabName = "table1",
fluidRow(
box(width = 12,
title = "Table 1",
dataTableOutput("table1"))
)
),
tabItem(tabName = "table2",
fluidRow(
box(width = 12,
title = "Table 2",
dataTableOutput("table2"))
)
)
)
)
)
server <- function(input, output, session) {
output$table1 <- renderDataTable({
datatable(
d1,
rownames = FALSE,
editable = FALSE,
selection = "none",
filter="top"
)
})
output$table2 <- renderDataTable({
datatable(
d2,
rownames = FALSE,
editable = FALSE,
selection = "none",
filter="top"
)
})
}
shinyApp(ui, server)
Here is a DT
variant of the reactable solution which uses dataTableProxy in combination with updateSearch()
to modify the table on the second tab.
library(shiny)
library(shinydashboard)
library(DT)
d1 <- data.frame(
name = c("Frank", "Emma", "Kurt", "Johanna", "Anna", "Ben", "Chris", "David", "Eva", "Felix", "Gina", "Hannah", "Iris", "Jack", "Karen", "Leo", "Mia", "Nina", "Omar", "Paul"),
team = c("A", "A", "B", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B", "A", "B"),
score = c(12, 15, 13, 13, 14, 11, 10, 16, 9, 8, 17, 14, 12, 13, 15, 16, 11, 10, 9, 8)
)
d2 <- data.frame(
name = c(
"Frank", "Frank", "Frank",
"Emma", "Emma", "Emma",
"Kurt", "Kurt", "Kurt",
"Johanna", "Johanna", "Johanna",
"Anna", "Anna", "Anna",
"Ben", "Ben", "Ben",
"Chris", "Chris", "Chris",
"David", "David", "David",
"Eva", "Eva", "Eva",
"Felix", "Felix", "Felix",
"Gina", "Gina", "Gina",
"Hannah", "Hannah", "Hannah",
"Iris", "Iris", "Iris",
"Jack", "Jack", "Jack",
"Karen", "Karen", "Karen",
"Leo", "Leo", "Leo",
"Mia", "Mia", "Mia",
"Nina", "Nina", "Nina",
"Omar", "Omar", "Omar",
"Paul", "Paul", "Paul"
),
match = c(
1, 2, 3, # Frank
1, 2, 3, # Emma
1, 2, 3, # Kurt
1, 2, 3, # Johanna
1, 2, 3, # Anna
1, 2, 3, # Ben
1, 2, 3, # Chris
1, 2, 3, # David
1, 2, 3, # Eva
1, 2, 3, # Felix
1, 2, 3, # Gina
1, 2, 3, # Hannah
1, 2, 3, # Iris
1, 2, 3, # Jack
1, 2, 3, # Karen
1, 2, 3, # Leo
1, 2, 3, # Mia
1, 2, 3, # Nina
1, 2, 3, # Omar
1, 2, 3 # Paul
),
score = c(
4, 4, 4, # Frank (12)
5, 5, 5, # Emma (15)
4, 4, 5, # Kurt (13)
4, 4, 5, # Johanna (13)
5, 4, 5, # Anna (14)
4, 4, 3, # Ben (11)
4, 3, 3, # Chris (10)
6, 5, 5, # David (16)
3, 3, 3, # Eva (9)
3, 3, 2, # Felix (8)
6, 6, 5, # Gina (17)
5, 5, 4, # Hannah (14)
4, 4, 4, # Iris (12)
4, 4, 5, # Jack (13)
5, 5, 5, # Karen (15)
6, 5, 5, # Leo (16)
4, 4, 3, # Mia (11)
4, 3, 3, # Nina (10)
3, 3, 3, # Omar (9)
3, 3, 2 # Paul (8)
)
)
ui <- dashboardPage(
dashboardHeader(title = "Test"),
dashboardSidebar(
sidebarMenu(
id = "tabs",
menuItem("Table 1", tabName = "table1", icon = icon("table")),
menuItem("Table 2", tabName = "table2", icon = icon("table"))
)
),
dashboardBody(
tabItems(
tabItem(tabName = "table1",
fluidRow(
box(width = 12,
title = "Table 1",
DTOutput("table1"))
)
),
tabItem(tabName = "table2",
fluidRow(
box(width = 12,
title = "Table 2",
DTOutput("table2"))
)
)
)
)
)
server <- function(input, output, session) {
output$table1 <- renderDT({
datatable(
d1,
rownames = FALSE,
editable = FALSE,
selection = "none",
filter="top"
) |>
formatStyle(1, cursor='pointer')
})
output$table2 <- renderDT({
datatable(
d2,
rownames = FALSE,
editable = FALSE,
selection = "none",
filter="top"
)
})
observeEvent(input$table1_cell_clicked$value, {
filterValues <- c(input$table1_cell_clicked$value, "", "")
proxy |>
updateSearch(keywords = list(columns = filterValues))
updateTabItems(session, "tabs", "table2")
})
outputOptions(output, "table2", suspendWhenHidden = FALSE)
proxy <- dataTableProxy('table2')
}
shinyApp(ui, server)
Concerning the question regarding the comparative studies between reactable
and DT
I do not such studies, however, using both solutions you should be able to test them for large data sets and compare the performance. On my machine, I tested it using a data set which was derived by using rep(., 100000)
on all columns of your data d1
and d2
and got a considerably fast result using DT
, whereas reactable
was very slow.