我正在开发一个基于用户输入创建新数据(Excel)文件的应用程序,还允许用户重新加载以前创建的文件,根据需要显示/更新内容。据我所知,这需要更新各种输入函数中的默认值(selected =)。
该应用程序的工作方式如下:用户选择页面数量和填充数据,每个页面都保存为Excel文件中的工作表。当用户想要更新文件以添加或删除页面时,用户从访问受限文件夹加载excel文件,并且每个页面中的每个选项卡中的数据都会填充。然后,用户根据需要编辑输入值并保存数据。
我可以使用updateSelectInput和类似的函数来更新字段。挑战在于,每页有大约30个输入字段,最多需要600页,需要600个更新语句。我正在寻找一种简单有效的方法来实现这一目标。以下是一个示例,几乎展示了我想要实现的基本概念。
library(shiny)
Sel <- data.frame(list(x = c("Sepal.Length", "Petal.Length","3" )))
ui <- fluidPage(
pageWithSidebar(
headerPanel('Iris k-means clustering'),
sidebarPanel(
fileInput("File1", "Load File", multiple = FALSE, accept = NULL, width = NULL,
buttonLabel = "Browse...", placeholder = "No file selected"),
actionButton("NewValues", "Values from file"),
tags$br(),tags$br(),
selectInput('xcol', 'X Variable', names(iris), selected = Sel$x[1]),
selectInput('ycol', 'Y Variable', names(iris), selected = Sel$x[2]),
selectInput('clusters', 'Cluster count', choices = seq(1:9), selected = Sel$x[3])
),
mainPanel(
plotOutput('plot1')
)
)
)
server <- function(input, output) {
Sel <- eventReactive(input$NewValues, {
inFile <- input$File1
read.csv(inFile$datapath, header = TRUE)
# The output of eventReactive function will be something equivalent to this:
# Sel <- data.frame(list(x = c("Petal.Length", "Sepal.Length","5" )))
})
selectedData <- reactive({
iris[, c(input$xcol, input$ycol)]
})
clusters <- reactive({
kmeans(selectedData(), input$clusters)
})
output$plot1 <- renderPlot({
palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
"#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))
par(mar = c(5.1, 4.1, 0, 1))
plot(selectedData(),
col = clusters()$cluster,
pch = 20, cex = 3)
points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
})
}
shinyApp(ui = ui, server = server)
加载数据(CSV)文件时,从eventReactive函数创建的Sel
数据框将等同于:
Sel <- data.frame(list(x = c("Petal.Length", "Sepal.Length","5" )))
答案 0 :(得分:2)
这是我能得到的最接近的:
library(shiny)
Sel2 <- data.frame(list(x = c("Sepal.Length", "Petal.Length","3" )))
ui <- fluidPage(
pageWithSidebar(
headerPanel('Iris k-means clustering'),
sidebarPanel(
fileInput("File1", "Load File", multiple = FALSE, accept = NULL, width = NULL,
buttonLabel = "Browse...", placeholder = "No file selected"),
actionButton("NewValues", "Values from file"),
tags$br(),tags$br(),
uiOutput("select1"),
#selectInput('xcol', 'X Variable', names(iris), selected = Sel$x[1]),
#selectInput('ycol', 'Y Variable', names(iris), selected = Sel$x[2]),
selectInput('clusters', 'Cluster count', choices = seq(1:9), selected = Sel2$x[3])
),
mainPanel(
plotOutput('plot1')
)
)
)
server <- function(input, output) {
Sel <- eventReactive(input$NewValues, {
inFile <- input$File1
read.csv(inFile$datapath, header = TRUE)
# The output of eventReactive function will be something equivalent to this:
# Sel <- data.frame(list(x = c("Petal.Length", "Sepal.Length","5" )))
})
output$select1<-renderUI({
element_number<- length(Sel2$x) - 1
lapply(1:element_number, function(i) {
selectInput(inputId=paste0("col",i),paste0("Col ",i),
choices = names(iris), selected = Sel2$x[i])})})
selectedData <- reactive({
element_number<- length(Sel2$x) - 1
vector <- lapply(1:element_number, function(i) {
a <- eval(parse(text=paste0("input$col",i)))})
b <-unlist(strsplit(as.character(vector), ","))
data <- iris[, b]
})
clusters <- reactive({
kmeans(selectedData(), input$clusters)
})
output$plot1 <- renderPlot({
palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
"#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))
par(mar = c(5.1, 4.1, 0, 1))
plot(selectedData(),
col = clusters()$cluster,
pch = 20, cex = 3)
points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
})
}
shinyApp(ui = ui, server = server)
有一个函数可以根据文件中的参数长度自动创建selectInput
,该文件被读取(但是长度 - 1,(Sel2$x) - 1
,因为最后一个参数是群集号,我找不到简单的解决方案来应对,但如果群集号始终是最后一个参数,那么它应该不是问题):
output$select1<-renderUI({
element_number<- length(Sel2$x) - 1
lapply(1:element_number, function(i) {
selectInput(inputId=paste0("col",i),paste0("Col ",i),
choices = names(iris), selected = Sel2$x[i])})})
此外,在创建的小部件的基础上,我能够将数据子集化以供进一步分析:
selectedData <- reactive({
element_number<- length(Sel2$x) - 1
vector <- lapply(1:element_number, function(i) {
a <- eval(parse(text=paste0("input$col",i)))})
b <-unlist(strsplit(as.character(vector), ","))
data <- iris[, b]
})