[解決済み] reactiveとobserveのメリットとobserveEventのメリット
疑問点
shiny reactive programmingについてできる限りのことを読みました。 私は少し混乱しています。 以下はすべて動作しますが、望ましい方法は何ですか、そしてなぜですか? 明らかに、以下の例は単純ですが、いずれかの方法でより大きなアプリケーションを作成するときに問題が発生するでしょうか?
私は、サーバーコード#1 のスタイルに引き寄せられる傾向があります。 理由は、if 文を分割することができるからです。 私にとっては、この方がずっと読みやすく思えます。 以下の簡単な例はそれほど複雑ではありませんが、サーバー コード 2 とサーバー コード 3 が、入れ子になった if / if else 文で非常に混乱することは容易に想像できます。
UI コード
library(shiny)
ui <- fluidPage(
selectInput(inputId = 'choice',
label = 'Choice',
choice = c('Hello','Goodbye'),
selected = c('Hello')
),
textOutput('result')
)
サーバーコード1
server <- function(input,output,session)({
text <- reactiveValues()
observe({
if (input$choice == 'Hello') {
text$result <- 'Hi there'
}
})
observe({
if (input$choice == 'Goodbye') {
text$result <- 'See you later'
}
})
output$result <- renderText({
text$result
})
})
shinyApp(ui = ui, server = server)
サーバーコード2
server <- function(input,output,session)({
getStatus <- reactive({
if (input$choice == 'Hello') {
'Hi there'
} else if (input$choice == 'Goodbye'){
'See you later'
}
})
output$result <- renderText({
getStatus()
})
})
shinyApp(ui = ui, server = server)
サーバーコード3
server <- function(input,output,session)({
text <- reactiveValues()
observeEvent(input$choice,{
if (input$choice == 'Hello') {
text$result <- 'Hi there'
} else if (input$choice == 'Goodbye') {
text$result <- 'See you later'
}
})
output$result <- renderText({
text$result
})
})
shinyApp(ui = ui, server = server)
どのように解決するのですか?
まず第一に、これは曖昧なもので、あまり直感的でないところがあります。
以下は、このトピックに関する私の最良の理解です。
まず
reactive
リアクティブ関数は、入力または他の変化する変数の状態を監視し、コードの他の場所で使用するためにその値を返すことができます。リアクティブ変数の監視は怠慢とみなされます。
"リアクティブ式は遅延評価を使用します。つまり、依存関係が変化してもすぐに再実行せず、他の誰かから呼び出されるまで待ちます(
ソース)
"です。
の中で変数を呼び出すことができるので、例2ではこれをうまく示していますね。
renderText
環境内で変数を呼び出すことができ、一度呼び出されると、反応呼び出しの中のコードが実行され、変数が再評価されます。
科学オタクにとっては、リアクティブ変数を呼び出す(それを観察する)ことによって、再評価によってそれが変化するという点で、これは量子力学によく似ていますが、大げさすぎますか?
では、次に
observe
Observeはreactiveに似ていますが、主な違いは自分以外の環境に値を返さないことと、遅延がないことです。オブザーブ関数は は、その環境内のすべてのリアクティブな値の変化を継続的に監視します。 そして、これらの値が変更されたときに、その環境内のコードを実行します。したがって、observeは再評価の前に呼ばれるのを待たないので、 "lazy"評価ではありません。繰り返しますが、observeから変数を代入することはできないことに注意してください。
実験のためです。
server <- function(input,output,session)({
observe({
if (input$choice == 'Hello') {
getStatus <- 'Hi there'
}
})
observe({
if (input$choice == 'Goodbye') {
getStatus <- 'See you later'
}
})
output$result <- renderText({
getStatus
})
})
shinyApp(ui = ui, server = server)
ここで重要なことは
observe
で実行されるコードの中で、外部の環境反応変数を操作することができることです。この例では
text <- reactiveValues()
を代入し、それを操作するために
text$result <- 'Hi there'
. を更新するようなこともできます。
selectInput
のような選択肢や、その他の輝くウィジェットもできますが、この環境では、上記の例の getStatus のような非反応変数を割り当てることができません。そして、この考え方は
observe
のドキュメントで言及されています。
オブザーバーはリアクティブな値を読み、リアクティブな式を呼び出すことができるという点で、リアクティブな式に似ています。そして、それらの依存関係が変化したときに自動的に再実行されます。しかし、リアクティブ式とは異なり、結果を出すことはなく、他のリアクティブ式の入力として使用することはできません。したがって、オブザーバはその副次的効果(例えばI/Oの実行など)においてのみ有用である( ソース )"です。
最後に
observeEvent
最適な使用方法は
observeEvent
を使用する最良の方法は、あるイベントまたは変数の変化を監視し、イベントが発生したときに起動するような、定義されたトリガーと考えることです。私は、ボタンへの入力を監視するために、最も一般的にこれを使用します。これは、ボタンが押された後に何かが起こるように定義されたイベントだからです。これは
isolate
環境を使用します。これは、この関数がどのように動作するかにぴったりの名前だと思います。
この環境の中では、たくさんの反応変数を呼び出すことができますが、トリガーとして定義するのは1つだけです。との主な違いは
observeEvent
と
observe
がトリガーとなり
observe
は何か変更があったときにいつでも実行され
observeEvent
はトリガーを待ちます。この環境は、反応しない変数を返さないという点で、observeと似ていることに注意してください。
概要
これらのアイデアをまとめた例を紹介します。
library(shiny)
ui<-
fluidPage(
fluidRow(
column(4,
h2("Reactive Test"),
textInput("Test_R","Test_R"),
textInput("Test_R2","Test_R2"),
textInput("Test_R3","Test_R3"),
tableOutput("React_Out")
),
column(4,
h2("Observe Test"),
textInput("Test","Test"),
textInput("Test2","Test2"),
textInput("Test3","Test3"),
tableOutput("Observe_Out")
),
column(4,
h2("Observe Event Test"),
textInput("Test_OE","Test_OE"),
textInput("Test_OE2","Test_OE2"),
textInput("Test_OE3","Test_OE3"),
tableOutput("Observe_Out_E"),
actionButton("Go","Test")
)
),
fluidRow(
column(8,
h4("Note that observe and reactive work very much the same on the surface,
it is when we get into the server where we see the differences, and how those
can be exploited for diffrent uses.")
))
)
server<-function(input,output,session){
# Create a reactive Evironment. Note that we can call the varaible outside same place
# where it was created by calling Reactive_Var(). When the varaible is called by
# renderTable is when it is evaluated. No real diffrence on the surface, all in the server.
Reactive_Var<-reactive({c(input$Test_R, input$Test_R2, input$Test_R3)})
output$React_Out<-renderTable({
Reactive_Var()
})
# Create an observe Evironment. Note that we cannot access the created "df" outside
# of the env. A, B,and C will update with any input into any of the three Text Feilds.
observe({
A<-input$Test
B<-input$Test2
C<-input$Test3
df<-c(A,B,C)
output$Observe_Out<-renderTable({df})
})
#We can change any input as much as we want, but the code wont run until the trigger
# input$Go is pressed.
observeEvent(input$Go, {
A<-input$Test_OE
B<-input$Test_OE2
C<-input$Test_OE3
df<-c(A,B,C)
output$Observe_Out_E<-renderTable({df})
})
}
shinyApp(ui, server)
reactive
変数を作成する
この変数はユーザーの入力によって時間と共に変化し、呼ばれたときだけという意味で "lazy"を評価します。
observe
反応イベントと変数を継続的に監視し、いつでも
いつでも
リアクティブ変数が環境(観測環境)で変更されるたびに、コードが評価されます。以前に定義されたリアクティブ変数の値を変更することができ、変数を作成/返却することはできません。
observeEvent
(ドミノ効果)
継続的に監視する
ワン
定義されたリアクティブ変数/イベント(トリガー)を継続的に監視し、そのトリガーの変更/入力によってトリガーがアクティブになったときにコードを実行します。事前に定義されたリアクティブ変数の値を変更することができ、変数の作成/返却はできません。
eventReactive
変数の作成
と同様に定義されたトリガーで
observeEvent
. これは、呼び出されたときではなく、トリガーによって評価される反応型変数が欲しいときに使います。
もし私の理解に間違いがあったり、より明確な説明が必要であれば、遠慮なくこの回答を編集していただければと思います。
関連
-
R言語です。「接続を開くことができません」解決策
-
R言語エラー:図の余白が大きすぎる 解決方法
-
[解決済み] R:自然対数を使った方程式をnlsで使う
-
[解決済み] require()とlibrary()の違いは何ですか?
-
[解決済み] 非常に大きなテーブルをデータフレームとして高速に読み込む
-
[解決済み] Rでロードされているパッケージのバージョンを調べるには?
-
[解決済み] ベクトル中のxの値を持つ要素の個数を数える
-
[解決済み] Rで文字列から最後のn文字を抽出する
-
[解決済み】エラー:Rで関数が見つかりませんでした。
-
[解決済み] ggplot2 で個々のファセットにテキストをアノテートする
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Rでファイルを読み込む際に、そのようなファイルまたはディレクトリが見つかりません。
-
R言語のエラーメッセージと関連する解決策
-
Rでエラー:単項演算子への引数が無効
-
R言語 - マトリックス
-
Rのexpand.grid()コマンド
-
[解決済み] HTML、PDF、DOCXで見栄えのするシンプルな手動のRMarkdownテーブル
-
[解決済み] Rで複数行のコメントを持つことは可能ですか?[重複している]。
-
[解決済み] data.frameの1つの列の名前を変更する方法は?
-
[解決済み] セッションが作成されません。このバージョンのChromeDriverはChromeバージョンにしか対応していません ChromeDriver ChromeでSeleniumを使用した場合の74エラー
-
[解決済み] R Shiny: reactiveValuesとreactiveの比較