2017-04-02 2 views
2

Shiny에서 첫 번째 앱을 제작 중이며 반응성에 대한 더 나은 아이디어를 얻으려고합니다. 나는 http://shiny.rstudio.com/tutorial/에 관한 튜토리얼을 보았다. 저는 테니스 관련 데이터 세트를 작업 중이며 'radarchart'패키지를 사용하여 radarchart를 만들고 싶습니다. 라디오 버튼을 렌더링하고 반응식을 사용하여 입력 상자를 성공적으로 선택할 수 있습니다.Shiny의 eventReactive() 함수를 사용하여 사용자 별 입력 데이터를 필터링 할 수 없습니다.

그러나 'Go!' 버튼을 누르면 콘솔에 "filter_impl의 오류 : 잘못된 길이 (0), 예상 : 27"이라는 오류가 표시됩니다. 앱 자체에는 오류가 표시되지 않지만 '실행!'을 클릭하면 렌더링되지 않습니다. 단추.

디버깅시 사용자가 입력 값 (server.R의 60-63 행)을 사용하여 데이터를 필터링하려고 할 때이 오류가 발생하는 것으로 나타났습니다. 내 주요 관심사는 사용자 선택에 따라 데이터를 필터링하는 것이고, 어떤 방식 으로든이를 수행 할 수는 없습니다. eventReactive(), observe() 및 reactiveValues ​​() 함수를 아무런 성공없이 사용하려고했습니다. 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 z에서 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) 

지금까지 레이더 차트를 방지으로 그려 할 때마다 재생되지 않습니다 세 입력 중 하나를 변경하면 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의 실행이 트리거되지 않습니다. 위의 코드에서 입력 $ 버튼을 변경하면 renderChartJSRadar이 실행됩니다.

+0

'scores'변수가 'scoresw'및 'scoresl'에 의존하기 때문에 문제가 계속 발생한다고 생각합니다. 'scoresl'은 반응 변수 'match()'에 의존합니다. 나는 'scoresw()', 'scoresl()'및 'scores()'로 변환하려고했지만 성공하지는 못했습니다. 벡터 'scoresw'및 'scoresl'을 초기화하는 데 문제가있을 수 있습니다. 나는 'scoresw'와 'scoresl'을 빈 벡터로 초기화하려고 시도했다. '일치'변수는 사용자가 입력을 변경할 때마다 변경됩니다. 내 '점수'변수가 작동하도록이 기능을 통합하는 방법을 알고 있습니까? 고맙습니다. –

+0

또한 코드의 중복 요소를 제거하고 renderchartJSRadar의 경우 NULL에 대한 필터링을 추가해 주셔서 감사합니다. 나는 그것을 실행 해 보았는데 어떻게 든 '점수'변수가 정확하게 계산되지 않는다는 것을 알았습니다. –

+0

Enzo의 의견을 정말 고맙게 생각합니다. 변수 'match'를 조금만 조정하면됩니다. 반응이 없으므로 'match()'를 사용할 필요가 없으며 모든 결과 반응에 대해 걱정할 필요가 없습니다. 마지막 질문이 하나 있는데 (너무 힘들지는 않지만) - 'Go'를 클릭하면 차트를 어떻게 업데이트 할 수 있습니까? 단추. 내 작업 코드에서는 세 입력 중 하나를 변경할 때마다 차트가 업데이트된다는 사실이 밝혀졌습니다. 사용자가 '이동'을 클릭 할 때만 업데이트하려면 어떻게해야합니까? 단추? 다시 한 번 감사드립니다! –

관련 문제