У меня есть блестящее приложение, состоящее из множества одинаковых частей, за исключением того, что они работают с разными фрагментами набора данных. Вот игрушечный пример, который независимо манипулирует и отображает два подмножества исходного набора данных:
# app.R
library(shinydashboard)
df <- data.frame(
id = 1:10,
group = rep(c("A", "B"), times = 5),
val = seq(1, 100, 10)
)
ui <- fluidPage(
fluidRow(
numericInput(
"A_multiplier",
"Multiplier:",
value = 1
),
tableOutput("A_table")
),
fluidRow(
numericInput(
"B_multiplier",
"Multiplier:",
value = 1
),
tableOutput("B_table")
)
)
server <- function(input, output) {
A_data <- reactive({
df <- df[df$group == "A", ]
df$val <- df$val * input$A_multiplier
df
})
output$A_table <- renderTable(A_data())
B_data <- reactive({
df <- df[df$group == "B", ]
df$val <- df$val * input$B_multiplier
df
})
output$B_table <- renderTable(B_data())
}
shinyApp(ui = ui, server = server)
Это тонна повторения кода, и ее становится очень сложно поддерживать по мере увеличения количества групп.
Что я хочу сделать, так это написать функции для генерации кода ui
и server
на основе групп, видимых в исходном df
, обрабатывая каждую группу одинаково.
Для ui
это довольно просто; Я могу заменить блок ui
следующим:
MakeGroupElements <- function(group) {
namer <- function(name) paste(group, name, sep = "_")
fluidRow(
numericInput(
namer("multiplier"),
"Multiplier:",
value = 1
),
tableOutput(namer("table"))
)
}
ui <- do.call(fluidPage, lapply(unique(df$group), MakeGroupElements))
для создания того же приложения, что и раньше, но более удобным для сопровождения.
Чего я не могу понять, так это того, как провести аналогичный рефакторинг на стороне сервера. Было бы легко, если бы у меня не было входных данных, но мне трудно правильно справляться с реактивностью.
Как я могу реорганизовать блок server
, чтобы предотвратить повторение кода?
Пояснение:
Сначала я не упомянул, что отделил генерацию данных от вызовов renderTable
, потому что в моем реальном приложении у меня есть множество выходных данных (таблиц, диаграмм, кнопок и т. д.), которые реактивно зависят от группового подмножества. данные, поэтому идеальное решение позволит такое расширение.
server
гибким, удобным для сопровождения способом, подобно тому, как я рефакторил сторонуui
выше. - person ClaytonJY   schedule 14.01.2016