Shiny 中的 selectizeInput 和 checkboxInput 不兼容
Incompatibility between selectizeInput and checkboxInput in Shiny
我正在创建一个应用程序,它从一个目录中获取一个文件并获取列名称,让用户有机会决定要使用哪个样本。
我没有上传文件,而是创建了一个数据框(类似于我的文件)并将其放入反应函数(这正是我上传文件时通常所做的)。
这是数据框
numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")
> df
S1 S2 S3 S4
1 5 345 55 10
我的应用程序有一个 checkboxInput
,您可以决定是否要对数据框进行对数运算。
如果我想比较 S1 和 S2,我意识到当我不点击进入框(并且我不做对数)时,样本不会改变。这就是我想要的。
但是,如果我决定计算对数(我点击复选框)示例 2 会发生变化(现在它比较 S1 和 S1,我真的不知道明白为什么,我不想)。
这是代码:
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("My app"),
sidebarLayout(
sidebarPanel(
uiOutput("selected_sample_one"),
uiOutput("selected_sample_two"),
checkboxInput("change_log2", "Log2 transformation", value = F),
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("plot")
)
)
)
# Define server
server <- function(input, output,session) {
data <- reactive({
numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")
if(input$change_log2 == TRUE){
df <- log2(df)
}
return(df)
})
samples_names <- reactive({
samples <- colnames(data())
return(samples)
})
output$selected_sample_one <- renderUI({
selectizeInput(inputId = "sample_one_axis", "Select the 1st sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
})
# With this function you can select which sample do you want to plot in the y-axis.
output$selected_sample_two <- renderUI({
selectizeInput(inputId = "sample_two_axis", "Select the 2nd sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
})
output$plot <- renderPlot({
barplot(c(data()[,input$sample_one_axis], data()[,input$sample_two_axis]))
})
}
# Run the application
shinyApp(ui = ui, server = server)
注:
如果我将列名保存到向量中,则对数和一切都有效。
而不是使用
samples_names <- reactive({
samples <- colnames(data())
return(samples)
})
如果我使用:samples_names <- c("S1", "S2", "S3", "S4")
并使用这个新向量 samples_names
更改 output$selected_sample_one
和 output$selected_sample_two
, 第二个样本不会更改(见新图)
但是,如果我增加列数或更改 table,此代码将不起作用。 因此,我将其写在反应函数...
有人知道怎么解决吗?
非常感谢
那是因为您的反应式数据框包含复选框信息,并且 sample_names 取决于该数据框。要将它们分开,请在执行日志操作的位置创建一个新数据框,使初始数据框不进行日志转换。试试这个
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("My app"),
sidebarLayout(
sidebarPanel(
uiOutput("selected_sample_one"),
uiOutput("selected_sample_two"),
checkboxInput("change_log2", "Log2 transformation", value = F)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("plot")
)
)
)
# Define server
server <- function(input, output,session) {
data <- reactive({
numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")
return(df)
})
data1 <- eventReactive(input$change_log2,{
df <- data()
if(input$change_log2 == TRUE){
df <- log2(df)
}
return(df)
})
samples_names <- reactive({
req(data())
samples <- colnames(data())
return(samples)
})
output$selected_sample_one <- renderUI({
selectizeInput(inputId = "sample_one_axis", "Select the 1st sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
})
# With this function you can select which sample do you want to plot in the y-axis.
output$selected_sample_two <- renderUI({
selectizeInput(inputId = "sample_two_axis", "Select the 2nd sample", choices=samples_names(), selected=samples_names()[2], options=list(maxOptions = length(samples_names())))
})
output$plot <- renderPlot({
req(input$sample_one_axis,input$sample_two_axis,data1())
barplot(c(data1()[,input$sample_one_axis], data1()[,input$sample_two_axis]))
})
}
# Run the application
shinyApp(ui = ui, server = server)
我正在创建一个应用程序,它从一个目录中获取一个文件并获取列名称,让用户有机会决定要使用哪个样本。
我没有上传文件,而是创建了一个数据框(类似于我的文件)并将其放入反应函数(这正是我上传文件时通常所做的)。
这是数据框
numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")
> df
S1 S2 S3 S4
1 5 345 55 10
我的应用程序有一个 checkboxInput
,您可以决定是否要对数据框进行对数运算。
如果我想比较 S1 和 S2,我意识到当我不点击进入框(并且我不做对数)时,样本不会改变。这就是我想要的。
但是,如果我决定计算对数(我点击复选框)示例 2 会发生变化(现在它比较 S1 和 S1,我真的不知道明白为什么,我不想)。
这是代码:
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("My app"),
sidebarLayout(
sidebarPanel(
uiOutput("selected_sample_one"),
uiOutput("selected_sample_two"),
checkboxInput("change_log2", "Log2 transformation", value = F),
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("plot")
)
)
)
# Define server
server <- function(input, output,session) {
data <- reactive({
numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")
if(input$change_log2 == TRUE){
df <- log2(df)
}
return(df)
})
samples_names <- reactive({
samples <- colnames(data())
return(samples)
})
output$selected_sample_one <- renderUI({
selectizeInput(inputId = "sample_one_axis", "Select the 1st sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
})
# With this function you can select which sample do you want to plot in the y-axis.
output$selected_sample_two <- renderUI({
selectizeInput(inputId = "sample_two_axis", "Select the 2nd sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
})
output$plot <- renderPlot({
barplot(c(data()[,input$sample_one_axis], data()[,input$sample_two_axis]))
})
}
# Run the application
shinyApp(ui = ui, server = server)
注:
如果我将列名保存到向量中,则对数和一切都有效。 而不是使用
samples_names <- reactive({
samples <- colnames(data())
return(samples)
})
如果我使用:samples_names <- c("S1", "S2", "S3", "S4")
并使用这个新向量 samples_names
更改 output$selected_sample_one
和 output$selected_sample_two
, 第二个样本不会更改(见新图)
但是,如果我增加列数或更改 table,此代码将不起作用。 因此,我将其写在反应函数...
有人知道怎么解决吗?
非常感谢
那是因为您的反应式数据框包含复选框信息,并且 sample_names 取决于该数据框。要将它们分开,请在执行日志操作的位置创建一个新数据框,使初始数据框不进行日志转换。试试这个
library(shiny)
# Define UI
ui <- fluidPage(
# Application title
titlePanel("My app"),
sidebarLayout(
sidebarPanel(
uiOutput("selected_sample_one"),
uiOutput("selected_sample_two"),
checkboxInput("change_log2", "Log2 transformation", value = F)
),
# Show a plot of the generated distribution
mainPanel(
plotOutput("plot")
)
)
)
# Define server
server <- function(input, output,session) {
data <- reactive({
numbers <- c(5,345,55,10)
df<-data.frame(t(numbers))
names(df) <- c("S1", "S2", "S3", "S4")
return(df)
})
data1 <- eventReactive(input$change_log2,{
df <- data()
if(input$change_log2 == TRUE){
df <- log2(df)
}
return(df)
})
samples_names <- reactive({
req(data())
samples <- colnames(data())
return(samples)
})
output$selected_sample_one <- renderUI({
selectizeInput(inputId = "sample_one_axis", "Select the 1st sample", choices=samples_names(), options=list(maxOptions = length(samples_names())))
})
# With this function you can select which sample do you want to plot in the y-axis.
output$selected_sample_two <- renderUI({
selectizeInput(inputId = "sample_two_axis", "Select the 2nd sample", choices=samples_names(), selected=samples_names()[2], options=list(maxOptions = length(samples_names())))
})
output$plot <- renderPlot({
req(input$sample_one_axis,input$sample_two_axis,data1())
barplot(c(data1()[,input$sample_one_axis], data1()[,input$sample_two_axis]))
})
}
# Run the application
shinyApp(ui = ui, server = server)