本章節(jié)主要內(nèi)容是如何實(shí)現(xiàn)包括確認(rèn),取消在內(nèi)的用戶反饋操作锐想。
內(nèi)容流程是先介紹validation
,用來(lái)讓用戶確認(rèn)自己的輸入。然后是介紹注意 notification
,用來(lái)編輯注意??警告文该编。然后是progress bars
,這個(gè)是用來(lái)展示進(jìn)度還有時(shí)間耗費(fèi)硕淑。最后會(huì)介紹confirmation
和undo
的操作课竣,用來(lái)確認(rèn)和取消操作嘉赎。
本章節(jié)主要是用shinyFeedback
包來(lái)實(shí)現(xiàn)以上的操作。
1 Validation驗(yàn)證
1.1 驗(yàn)證輸入Input
具體操作大概分成兩步于樟。2 steps.
首先要在ui里加入useShinyFeedback()
公条。這一步的作用是自動(dòng)設(shè)置需要的HTML和JAVA腳本。
ui <- fluidPage(
shinyFeedback::useShinyFeedback(),
numericInput("n", "n", value = 10),
textOutput("half")
)
然后需要在server端設(shè)置反饋信息迂曲。種類分成feedback, feedbackWarning, feedbackDanger, feedbackSuccess
靶橱。不管是哪一種包含三個(gè)參數(shù)信息。
-
inputId
: feedback對(duì)象的ID -
show
:有關(guān)是否要展示feedback信息的一個(gè)邏輯變量 -
text
: 需要展示的feedback信息
還有color
和icon
參數(shù)可以設(shè)置路捧,詳細(xì)信息可以參考幫助文件关霸。
server <- function(input, output, session) {
half <- reactive({
even <- input$n %% 2 == 0
# inputID= "n"
# show= !even
# text= "Please select an even number"
shinyFeedback::feedbackWarning("n", !even, "Please select an even number")
input$n / 2
})
output$half <- renderText(half())
}
shinyApp(ui, server)
上面的代碼雖然成功顯示了警告文,但還是運(yùn)行了代碼給出了結(jié)果杰扫。理想的情況是不運(yùn)行谒拴。可以用到之前提過(guò)的req()
函數(shù)涉波。 之前文章里沒(méi)有說(shuō)明這是什么函數(shù)英上,其實(shí)是”require”的縮寫(xiě)。
server <- function(input, output, session) {
half <- reactive({
even <- input$n %% 2 == 0
shinyFeedback::feedbackWarning("n", !even, "Please select an even number")
req(even)
input$n / 2
})
output$half <- renderText(half())
}
1.2 用req()
取消代碼執(zhí)行
如果想實(shí)現(xiàn)在沒(méi)有任何操作的情況下不顯示任何信息啤覆,可以用req()
函數(shù)苍日。
通常在下面的三個(gè)情況下可能會(huì)用到
-
textInput()
, 設(shè)置默認(rèn)輸入是value=””
,這個(gè)時(shí)候不會(huì)在有輸入前跳出任何信息 -
selectInput()
窗声,可以創(chuàng)建一個(gè)空白選項(xiàng) -
fileInput()
相恃,在有輸入之前就是一個(gè)空白項(xiàng)
舉個(gè)例子,如果不用req()
就會(huì)顯示錯(cuò)誤信息笨觅,雖然不會(huì)影響整體拦耐,但是不美觀。
ui <- fluidPage(
selectInput("language", "Language", choices = c("", "English", "Maori")),
textInput("name", "Name"),
textOutput("greeting")
)
server <- function(input, output, session) {
greetings <- c(
English = "Hello",
Maori = "Kia ora"
)
output$greeting <- renderText({
paste0(greetings[[input$language]], " ", input$name, " !")
})
}
加入req()
以后就可以解決见剩。 不符合邏輯要求的話所有下游的計(jì)算都會(huì)被取消杀糯。
server <- function(input, output, session) {
greetings <- c(
English = "Hello",
Maori = "Kia ora"
)
output$greeting <- renderText({
req(input$language, input$name)
paste0(greetings[[input$language]], " ", input$name, "!")
})
}
req()
有好幾種用法,一種就是剛才的req(input$x)
苍苞,只有指定數(shù)值以后才執(zhí)行接下來(lái)的代碼固翰。還有一種是req(input$a > 0)
添加邏輯判斷函數(shù)。
1.3 req()
和驗(yàn)證
結(jié)合req()
和驗(yàn)證可以實(shí)現(xiàn)比較復(fù)雜的功能羹呵。比方說(shuō)在輸入錯(cuò)誤的時(shí)候不要顯示空白骂际,而是把結(jié)果顯示停留在之前的結(jié)果上「曰叮可以用到exists
函數(shù)來(lái)根據(jù)數(shù)據(jù)集是否存在的邏輯結(jié)果來(lái)激活feedbackDanger
歉铝,流程歸納一下就是如下:
輸入datasets名字,req()
確認(rèn)到輸入以后執(zhí)行操作凑耻,確認(rèn)datasets名字存在太示,不存在的話發(fā)出警告文柠贤,并且cancel output。讓結(jié)果停留在之前先匪。
ui <- fluidPage(
shinyFeedback::useShinyFeedback(),
textInput("dataset", "Dataset name"),
tableOutput("data")
)
server <- function(input, output, session) {
data <- reactive({
req(input$dataset)
exists <- exists(input$dataset, "package:datasets")
shinyFeedback::feedbackDanger("dataset", !exists, "Unknown dataset")
req(exists, cancelOutput = TRUE)
get(input$dataset, "package:datasets")
})
output$data <- renderTable({
head(data())
})
}
get()
函數(shù)https://rdrr.io/r/base/get.html
1.4 Validate輸出
盡管之前介紹的shinyFeedback
看上去很有用种吸,但是在面對(duì)多個(gè)錯(cuò)誤的復(fù)雜條件的情況下也會(huì)顯得無(wú)能為力,這時(shí)候就要用到validate()
函數(shù)了呀非。
舉個(gè)例子坚俗,我們需要計(jì)算一個(gè)輸入值的平方,對(duì)數(shù)岸裙,開(kāi)根號(hào)值猖败。需要對(duì)數(shù)和開(kāi)根號(hào)計(jì)算時(shí)對(duì)于小于0的輸入值報(bào)錯(cuò)。
注意一下switch
的用法降允。
ui <- fluidPage(
numericInput("x", "x", value = 0),
selectInput("trans", "transformation",
choices = c("square", "log", "square-root")
),
textOutput("out")
)
server <- function(input, output, session) {
output$out <- renderText({
if (input$x < 0 && input$trans %in% c("log", "square-root")) {
validate("x can not be negative for this transformation")
}
switch(input$trans,
square = input$x ^ 2,
"square-root" = sqrt(input$x),
log = log(input$x)
)
})
}