r - RShiny : mainPanel 行为随输入而变化
问题描述
每张图片上方都有一个操作按钮。但根据 input$n 的奇偶性(在侧边栏面板内的数字输入中),它的工作方式会有所不同。如果 input$n 是奇数,单击按钮会更改标签,这就是我想要的。否则,它没有。
请分别找到附加的服务器和用户界面:
require(png)
require(shiny)
require(shinyjs)
########## PRE-PROCESSING
Nsub <- 5
Nimg <- 10
nvar <- 112*92
N <- Nsub * Nimg
#stocker noms fichiers et images
init <- function(){
listFiles <- list()
listDataMat <- list()
excluded <- list()
for( sub in 1:Nsub ){
listLabel <- c()
DataMat <- matrix(nrow=Nimg,ncol=nvar)
for( img in 1:Nimg ) {
fname <- paste("www/s",sub,"_",img,".png",sep="")
listLabel <- c(listLabel,fname)
d <- readPNG(fname)
DataMat[img,] <- matrix(d,ncol=nvar)
}
listFiles[[sub]] <- listLabel
listDataMat[[sub]] <- DataMat
excluded[[sub]] <- rep(FALSE,10)
}
list(listFiles,listDataMat,excluded)
}
lists <- init()
listFiles <- lists[[1]]
listDataMat <- lists[[2]]
excluded <- lists[[3]] #noms fichier exclus de database // %in%
remove(lists)
############ HELPER FUNC
#afficher images d'une classe
dispImgs <- function(variable,ind){
if(variable>=1){
DataMat <- listDataMat[[variable]]
}else{
DataMat <- listDataMat[["0"]]
}
result <- list()
outfile <- tempfile(fileext = ".png")
sample <- matrix(DataMat[ind,], nrow = 112, ncol = 92)
writePNG(sample, target = outfile)
im <- list(src = outfile,
contentType = "image/png",
alt = "Normalement, on devrait voir une photo",
width = 92,
height = 112
)
im
}
###########SERVER
server <- function(input,output,session){
excluded <- reactiveValues(ls = excluded)
# vals <- reactiveValues()
# vals$n_sample <- 10
# vals$n_rows <- *
# vals$last_row <- n_sample%%5
#
observeEvent(input$n,{
n_sample <- ifelse(input$n==0,nrow(listDataMat[["0"]]),nrow(listDataMat[[input$n]]))
n_rows <- round(n_sample/5)
last_row <- n_sample%%5
#creating event listener
lapply(
X = 1:n_sample,
FUN = function(i){
observeEvent(input[[paste0("out",i)]], {
excluded$ls[[input$n]][i] <- !excluded$ls[[input$n]][i]
updateActionButton(session, paste0("out",i),
label = ifelse(excluded$ls[[input$n]][i],"Inclure","Exclure"))
print(excluded$ls[[input$n]])
})
}
)
})
img_widget <- function(i) {
if(input$n==0){
column(2,
renderImage({
dispImgs(input$n,i)
},outputArgs = c(height="200px")
)
)
}else{
column(2,
actionButton(paste0("out",i), label = ifelse(excluded$ls[[input$n]][i],"Inclure","Exclure")),
renderImage({
dispImgs(input$n,i)
},
outputArgs = c(height="200px")
)
)
}
}
output$mainPanel <- renderUI({
mainPanel(
h2(paste("Les 10 photos de l'individu", input$n)),
# if(n_rows!=0){
# for(i in 1:n_rows){
# fluidRow(
# width=10,
# lapply(
# X = 1+5*(i-1):5*i,
# FUN = img_widget
# )
# )
# }
# }
# if(last_row!=0){
# fluidRow(
# width=10,
# lapply(
# X = 1+5*(n_rows-1):5*(n_rows-1)+last_row,
# FUN = img_widget
# )
# )
# }
fluidRow(
width=10,
lapply(
X = 1:5,
FUN = img_widget
)
),
fluidRow(
width=10,
lapply(
X = 6:10,
FUN = img_widget
)
)
)
})
}
require(png)
require(shiny)
######### HELPER FUNC
########## UI
ui <- fluidPage(
# Titre
headerPanel("Banque de photos pour reconnaissance faciale"),
sidebarLayout(
sidebarPanel(
numericInput('n', "Numéro de l'individu à afficher", 1, min = 0, max = 40, step = 1)
),
uiOutput("mainPanel")
)
)
为了重现该问题,您需要一个包含名为“s1_2.png”的图片的文件夹“www”,其中 1 是类,2 是图片索引。每个类只能定义 5 张图片 (S[1-5]_[1-5].png)。因此,自然会出现轻微的显示问题。
编辑:忘了提到图片需要灰度。
解决方案
查看print(excluded$ls[[input$n]])
输出,似乎每次input$n
触发时,它都会增加updateActionButton()
触发 any 时将启动的数量input$outN
。
例如,触发 2 次input$n
然后单击任何input$outN
按钮将启动updateActionButton
两次而不是一次。所以它首先排除但然后重新包含您的样本。当input$n
被触发奇数次时,它最终以排除样本而结束,这就是它似乎起作用的原因。
不知道为什么会发生这种情况,但这肯定是因为有两个嵌套的observeEvent
. 可能已经观察到了类似的行为(双关语)。
如果你不嵌套这两个observeEvent
,它会按预期工作:
n_sample <- nrow(listDataMat[[1]])
observeEvent(input$n,{
n_sample <- ifelse(input$n==0,nrow(listDataMat[["0"]]),nrow(listDataMat[[input$n]]))
n_rows <- round(n_sample/5)
last_row <- n_sample%%5
})
#creating event listener
lapply(
X = 1:n_sample,
FUN = function(i){
observeEvent(input[[paste0("out",i)]], {
excluded$ls[[input$n]][i] <- !excluded$ls[[input$n]][i]
updateActionButton(session, paste0("out",i),
label = ifelse(excluded$ls[[input$n]][i],"Inclure","Exclure"))
print(excluded$ls[[input$n]])
})
}
)
但是您需要在n_sample
第一个变量之外定义变量,observeEvent
以便函数可以使用它lapply
。我通过“静态”定义它进行了简化,但您需要一些reactiveValue
,以便在触发第一个observeEvent
.
推荐阅读
- ios - SwiftUI - 此代码是否实例化了一个新的场景对象?
- javascript - 即使我的代码是正确的,为什么当我尝试 npm start 时我的 electron.js 应用程序不会打开?
- python - Python-Bitcoinlib - FileNotFoundError:找不到模块'libeay32'
- c - 拆分C链表而不复制
- python - Linux中Python子进程之间管道的困难
- networking - K8s 是否在普通的 Layer2 网络基础设施上运行?
- c# - 压缩后无效的 C# Zip 文件
- javascript - 我如何让每个人都有不同的频道(实时聊天应用程序)
- python - Telegram Telethon:如果您知道频道哈希,如何获取消息
- javascript - multiple conditions to Show input field only if a specific option is selected