2017-04-02 9 views
2

私はShinyの最初のアプリケーションを構築しており、反応性についてのより良い考えを得ることを意味しています。私はhttp://shiny.rstudio.com/tutorial/のチュートリアルを終えました。私はテニス関連のデータセットに取り組んでおり、「radarchart」というパッケージを使って、radarchartを作成したいと思っています。私はラジオボタンをレンダリングし、反応式を使って入力ボックスをうまく選択することができます。ShinyのeventReactive()関数を使用してユーザーごとのデータをフィルタリングできません

ただし、[Go!]をクリックすると、ボタンをクリックすると、コンソールに次のエラーが表示されます。「filter_implのエラー:不正な長さ(0)、予想:27」。アプリ自体にエラーは表示されませんが、「Go!」をクリックするだけでレンダリングはありません。ボタン。

デバッグ時に、ユーザーの入力値の選択(server.Rの60〜63行目)を使用してデータをフィルタリングしようとしているときに、このエラーが発生することがわかりました。私の主な関心事は、ユーザーの選択に応じてデータをフィルタリングすることです。私は決してそれを行うことができません。私はeventReactive()、observe()、およびreactValues()関数を何も成功せずに使用しようとしました。私はeventReactive関数内でrenderChartJSRadar関数をラップしましたが、それが正しいかどうかはわかりません。

この場合の反応性がどのように機能するのか、それを機能させるためには何が欠けているのか、私は混乱します。コードは以下の通りです。私は本当に助けに感謝します。

ui.R

library(xlsx) 
library(shiny) 
library(dplyr) 
source("chart.R") 
library(radarchart) 

shinyUI(fluidPage(

      titlePanel("Match Radar Chart"), 

      sidebarLayout(
      sidebarPanel(
       selectInput("var", 
         label = "Choose a tournament", 
         choices = tour, 
         selected = "Auckland"), 

       uiOutput("radioButtons"), 
       uiOutput("selectControls"), 
       actionButton("update", "Go!") 
      ), 

       mainPanel(
       chartJSRadarOutput("radarChart", width = "450", height = "300") 
      ) 
     ) 
)) 

server.R

library(xlsx) 
library(dplyr) 
library(radarchart) 
library(data.table) 
source("chart.R") 
library(shiny) 
library(grDevices) 


shinyServer(function(input, output, session) { 

    output$radioButtons <- renderUI({ 
       dataInput <- reactive({input$var}) 
       z <- dataInput() 
       buttons <- numrounds(z) 
       radioButtons("button", "Select a round: ", choices = buttons, inline = FALSE) 
     }) 

    output$selectControls <- renderUI({ 
       dataInput <- reactive({input$var}) 
       z <- dataInput() 
       dataInput1 <- reactive({input$button}) 
       y <- dataInput1() 
       winner <- mydata %>% 
         filter(tourney_name == z) %>% 
         filter(round == y) %>% 
         select(winner_name) %>% 
         sapply(as.character) %>% 
         as.vector() 

       loser <- mydata %>% 
         filter(tourney_name == z) %>% 
         filter(round == y) %>% 
         select(loser_name) %>% 
         sapply(as.character) %>% 
         as.vector() 

       players <- c(winner, loser) 

       selectInput("select", "Select a match: ", choices = players, selected = 1, multiple = FALSE) 

    })  

      output$radarChart <- eventReactive(input$update, { 
      renderChartJSRadar({ 
      dataInput1 <- reactive({input$var}) 
      z <- dataInput1() 
      dataInput2 <- reactive({input$button}) 
      y <- dataInput2() 
      dataInput3 <- reactive({input$select}) 
      x <- dataInput3() 
      match <- mydata %>% 
       filter(tourney_name == z) %>% 
       filter(round == y) %>% 
       filter(winner_name == x) 

      scoresw <- vector() 
      scoresl <- vector() 
      for(j in 25:33) { 
        scoresw <- c(scoresw, match()[j]) 
      } 
      for(j in 34:42) { 
        scoresl <- c(scoresl, match()[j]) 
      } 

      scores <- list(winner = scoresw, loser = scoresl) 
      labs <- c("Aces", "Double Faults", "Service points", "1st Service In", "1st Service won", "2nd Service won", "Service games", "Break points saved", "Break points faced") 
      c <- grDevices::col2rgb(c("green", "red")) 

      chartJSRadar(scores = scores, labs = labs, labelSize = 15, colMatrix = c) 
    }) 
    }) 

}) 

chart.R

mydata <- read.csv("Match Radar/Data/atp_matches_2014_edited.csv", header = TRUE) 
tour <- unique(data$tourney_name) 


numrounds <- function(z) { 
    for(i in 1:64) { 
    rounds <- mydata %>% 
     filter(tourney_name == z) %>% 
     summarise(number = n_distinct(round)) 

    if(rounds == 3){ 
     buttons <- c("RR", "SF", "F") 
    } 
    else if(rounds == 5){ 
     buttons <- c("R32", "R16", "QF", "SF", "F") 
    } 
    else if(rounds == 6){ 
     buttons <- c("R64", "R32", "R16", "QF", "SF", "F") 
    } 
    else { 
     buttons <- c("R128", "R64", "R32", "R16", "QF", "SF", "F") 
    } 
    } 
    buttons 
} 

答えて

1

私は、単一のファイルに自分のアプリを入れて簡単にデバッグできます。

メニューが正しく表示されます。光沢のある部分が機能するはずです。基本的な考え方は、入力変数がすでに反応しているため、反応関数を構築するためには少なくとも(この場合は)冗長です。

renderChartJSRadarでは、yとxは正しく初期化されます(最初のNULLケースは破棄されます)。また、renderChartJSRadarはすでに反応していますが、 "熱心に反応する"ので、他の値が設定されていないときに開始されるため、NULLのフィルタリングが行われます。

renderChartJSRadarには、スコアを計算するRロジックで実行するデバッグがあります。現在、エラーがあります:私はあなたが達成したいものを言うことができないとして、残念ながら私は助けることができない - と私はテニスをしていない:)

library(xlsx) 
library(dplyr) 
library(radarchart) 
# library(data.table) 
# source("chart.R") 
library(shiny) 
library(grDevices) 

#------------------------------------------------------------------------------ 

mydata <- read.csv("./data/atp_matches_2014.csv", header = TRUE) 
tour <- unique(mydata$tourney_name) 

numrounds <- function(z) { 
    for(i in 1:64) { 
    rounds <- mydata %>% 
     filter(tourney_name == z) %>% 
     summarise(number = n_distinct(round)) 

    if(rounds == 3){ 
     buttons <- c("RR", "SF", "F") 
    } 
    else if(rounds == 5){ 
     buttons <- c("R32", "R16", "QF", "SF", "F") 
    } 
    else if(rounds == 6){ 
     buttons <- c("R64", "R32", "R16", "QF", "SF", "F") 
    } 
    else { 
     buttons <- c("R128", "R64", "R32", "R16", "QF", "SF", "F") 
    } 
    } 
    return(buttons) 
} 

#------------------------------------------------------------------------------ 

ui <- fluidPage(

    titlePanel("Match Radar Chart"), 

    sidebarLayout(
    sidebarPanel(
     selectInput("var", 
        label = "Choose a tournament", 
        choices = tour, 
        selected = "Auckland"), 

     uiOutput("radioButtons"), 
     uiOutput("selectControls"), 
     actionButton("update", "Go!") 
    ), 

    mainPanel(
     chartJSRadarOutput("radarChart", width = "450", height = "300") 
    ) 
) 
) 

#------------------------------------------------------------------------------ 

server <- function(input, output, session){ 
    session$onSessionEnded({ stopApp }) 

    output$radioButtons <- renderUI({ 
    # dataInput <- reactive({input$var}) 

    z <- input$var 
    buttons <- numrounds(z) 
    radioButtons("button", "Select a round: ", choices = buttons, inline = FALSE) 
    }) 

    output$selectControls <- renderUI({ 

    # dataInput <- reactive({input$var}) 
    z <- input$var 
    # dataInput1 <- reactive({input$button}) 
    y <- input$button #dataInput1() 
    winner <- mydata %>% 
     filter(tourney_name == z) %>% 
     filter(round == y) %>% 
     select(winner_name) %>% 
     sapply(as.character) %>% 
     as.vector() 

    loser <- mydata %>% 
     filter(tourney_name == z) %>% 
     filter(round == y) %>% 
     select(loser_name) %>% 
     sapply(as.character) %>% 
     as.vector() 

    players <- c(winner, loser) 

    selectInput("select", "Select a match: ", choices = players, selected = 1, multiple = FALSE) 

    })  

    output$radarChart <- renderChartJSRadar({ 
    # browser() 
     if(is.null(input$button)) return() 
     if(is.null(input$select)) return() 
     # dataInput1 <- reactive({input$var}) 
     z <- input$var # dataInput1() 
     # dataInput2 <- reactive({input$button}) 
     y <- input$button # dataInput2() 
     # dataInput3 <- reactive({input$select}) 
     x <- input$select # dataInput3() 
     match <- mydata %>% 
     filter(tourney_name == z) %>% 
     filter(round == y) %>% 
     filter(winner_name == x) 

     scoresw <- vector() 
     scoresl <- vector() 
     for(j in 25:33) { 
     scoresw <- c(scoresw, match()[j]) 
     } 
     for(j in 34:42) { 
     scoresl <- c(scoresl, match()[j]) 
     } 

     scores <- list(winner = scoresw, loser = scoresl) 
     labs <- c("Aces", "Double Faults", "Service points", "1st Service In", "1st Service won", "2nd Service won", "Service games", "Break points saved", "Break points faced") 
     c <- grDevices::col2rgb(c("green", "red")) 

     chartJSRadar(scores = scores, labs = labs, labelSize = 15, colMatrix = c) 

    }) 

} 
#------------------------------------------------------------------------------ 

shinyApp(ui, server) 

限り毎回ユーザーを描画するレーダーチャートを防ぐなど3つの入力のうちの1つを変更します。これはisolateを使用して可能です。例えば

(コードテストしていないが、それは動作するはずです:))

output$radarChart <- renderChartJSRadar({ 
     if(is.null(input$button)) return() 
     isolate({ 
      if(is.null(input$select)) return() 
      z <- input$var # dataInput1() 
      y <- input$button # dataInput2() 
      x <- input$select # dataInput3() 
     }) 

または非常に類似したもの。例えば、input$varとする。 isolateの範囲内であるため、ユーザーによる変更はrenderChartJSRadarの実行をトリガーしません。上記のコードでは、入力$ buttonの変更だけがrenderChartJSRadarの実行をトリガします。

+0

'scores'変数は 'scoresw'と 'scoresl'に依存するため、この問題は解決しないと思われます。これは、反応変数 'match()'に依存します。私は 'scoresw()'、 'scoresl()'、 'scores()'に変換しようとしましたが、成功しませんでした。ベクトル 'scoresw'と 'scoresl'の初期化に問題がある可能性があります。私は空のベクトルとして 'scoresw'と 'scoresl'を初期化しようとしました。 「一致」変数は、ユーザーが入力を変更するたびに変更されます。私の「スコア」変数を機能させるために、この機能をどのように組み込むべきか考えていますか?ありがとうございました。 –

+0

また、コード内の冗長な要素を削除して、renderchartJSRadarの場合にNULLのフィルタリングを追加してくれてありがとうございました。私はそれを実行しようとしたと私は何とか 'スコア'変数が正しく計算されていないことを参照してください。 –

+0

私はあなたの入力エンツォに本当に感謝しています、私は変数 'マッチ'を微調整することによってそれを動作させることができました。それは反応的ではないことが判明したので、私は 'match()'を使う必要はなく、すべての結果的反応性について心配する必要はありません。私は最後の質問が1つしかありませんでしたが(それほど厳しいことではありませんが)、「Go」をクリックしてチャートを更新するにはどうすればよいですか?ボタン。私の作業コードでは、3つの入力のいずれかを変更するたびにチャートが更新されることが分かりました。ユーザーが「Go!」をクリックしたときにのみ更新したい場合はどうすればよいですか?ボタン?再度、感謝します! –

関連する問題