formattable 中的动态条件
Dynamic conditions in formattable
我正在使用 formattable 在 shiny 应用程序的 table 中实现一些条件颜色格式。例如,假设我想为低于值 2 的单元格着色,绿色,高于 5 的单元格,红色,2 和 5 之间的单元格,橙色。我会这样写我的格式化函数:
formatter(
"span",
style = x ~ style(
color = 'white',
'background-color' =
ifelse(x > 5, "red",
ifelse(x > 2 & x <= 5, "orange",
"green"))))
但是,我真正想做的是让用户能够更改这些颜色阈值,即 2 和 5。
假设 user_low 和 user_high 由用户定义:
col_format <-
formatter(
"span",
style = x ~ style(
color = 'white',
'background-color' =
ifelse(x > input$user_high, "red",
ifelse(x > input$user_low & x <= input$user_high, "orange",
"green"))))
如果我现在尝试将此格式化程序输入我闪亮的应用程序中的格式table:
formattable(mtcars, col_format)
我收到以下错误:
'col_format' of mode 'function' was not found
看似 input$user_low 和 input$user_high 未被评估,而是在格式化程序中被视为字符串。我试过 eval(), eval(parse()), 都没有用。
有什么想法吗?
您的代码几乎可以正常运行,但是如果您想在表达式中使用 input$user_high
等输入元素,则必须使用 reactive
.
这将按顺序发生:
- 输入元素的值发生变化。 (
input$user_low
或 input$user_high
)
- 列格式化条件 (
col_format
) 将更新,因为它的依赖关系发生了变化。
- 重新渲染
dataTableOutput
因为它依赖于 col_format
。
示例代码:
library(shiny)
library(formattable)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput("user_low", "User low", value = 2, min = 1, max = 5),
numericInput("user_high", "User high", value = 8, min = 6, max = 10)
),
mainPanel(
DT::dataTableOutput("table")
)
)
)
server <- function(input, output) {
output$table <- DT::renderDataTable( {
as.datatable(formattable(mtcars, list(
cyl = col_format()
)))
})
col_format <- reactive( {
formatter(
"span",
style = x ~ style(
color = 'white',
'background-color' =
ifelse(x > input$user_high, "red",
ifelse(x > input$user_low & x <= input$user_high, "orange",
"green"))))
})
}
shinyApp(ui, server)
编辑:要将格式化程序应用于每一列(根据您的评论),您可以使用 lapply
,如 动态生成Formattable vignette 中的格式化程序 部分。下面的代码将格式应用于整个数据集。
代码:
output$table <- DT::renderDataTable( {
as.datatable(formattable(mtcars, lapply(1:ncol(mtcars), function(col) {
area(row = 1:nrow(mtcars), col) ~ col_format()
})))
})
我正在使用 formattable 在 shiny 应用程序的 table 中实现一些条件颜色格式。例如,假设我想为低于值 2 的单元格着色,绿色,高于 5 的单元格,红色,2 和 5 之间的单元格,橙色。我会这样写我的格式化函数:
formatter(
"span",
style = x ~ style(
color = 'white',
'background-color' =
ifelse(x > 5, "red",
ifelse(x > 2 & x <= 5, "orange",
"green"))))
但是,我真正想做的是让用户能够更改这些颜色阈值,即 2 和 5。
假设 user_low 和 user_high 由用户定义:
col_format <-
formatter(
"span",
style = x ~ style(
color = 'white',
'background-color' =
ifelse(x > input$user_high, "red",
ifelse(x > input$user_low & x <= input$user_high, "orange",
"green"))))
如果我现在尝试将此格式化程序输入我闪亮的应用程序中的格式table:
formattable(mtcars, col_format)
我收到以下错误:
'col_format' of mode 'function' was not found
看似 input$user_low 和 input$user_high 未被评估,而是在格式化程序中被视为字符串。我试过 eval(), eval(parse()), 都没有用。
有什么想法吗?
您的代码几乎可以正常运行,但是如果您想在表达式中使用 input$user_high
等输入元素,则必须使用 reactive
.
这将按顺序发生:
- 输入元素的值发生变化。 (
input$user_low
或input$user_high
) - 列格式化条件 (
col_format
) 将更新,因为它的依赖关系发生了变化。 - 重新渲染
dataTableOutput
因为它依赖于col_format
。
示例代码:
library(shiny)
library(formattable)
library(DT)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
numericInput("user_low", "User low", value = 2, min = 1, max = 5),
numericInput("user_high", "User high", value = 8, min = 6, max = 10)
),
mainPanel(
DT::dataTableOutput("table")
)
)
)
server <- function(input, output) {
output$table <- DT::renderDataTable( {
as.datatable(formattable(mtcars, list(
cyl = col_format()
)))
})
col_format <- reactive( {
formatter(
"span",
style = x ~ style(
color = 'white',
'background-color' =
ifelse(x > input$user_high, "red",
ifelse(x > input$user_low & x <= input$user_high, "orange",
"green"))))
})
}
shinyApp(ui, server)
编辑:要将格式化程序应用于每一列(根据您的评论),您可以使用 lapply
,如 动态生成Formattable vignette 中的格式化程序 部分。下面的代码将格式应用于整个数据集。
代码:
output$table <- DT::renderDataTable( {
as.datatable(formattable(mtcars, lapply(1:ncol(mtcars), function(col) {
area(row = 1:nrow(mtcars), col) ~ col_format()
})))
})