Post
새소식
- Chirpy Theme 7.2.0 업데이트

Reactive

Reactive

Reactive

사용할 데이터

구현할 app

기능 구현

1
2
3
4
5
6
7
8
9
output$plot <- renderPlot({
  data <- getSymbols(input$symb, src = "yahoo",
                     from = input$dates[1],
                     to = input$dates[2],
                     auto.assign = FALSE)

  chartSeries(data, theme = chartTheme("white"),
              type = "line", log.scale = input$log, TA = NULL)
})

위와 같이 기능을 구현할 경우 동작은 하지만 ui 변경 때마다 데이터를 다시 읽어 화면에 출력하는 문제점이 발생한다. 즉, log.scale = input$log과 같이 데이터에는 변경이 없더라도 renderPlot() 함수는 재실행 된다.

기능 개선

위 예제 코드에서 renderPlot() 함수가 호출 되더라도 input$symb, input$datas에 변화가 없는 경우 data를 다시 읽어 오지 않도록 개선한다. 즉, ui에서 변경된 값이 있는 경우만 render*() 함수가 동작하도록 한다.

1
2
3
4
5
6
dataInput <- reactive({
  getSymbols(input$symb, src = "yahoo",
    from = input$dates[1],
    to = input$dates[2],
    auto.assign = FALSE)
})

reactive()({}) 구문을 통해 구현이 가능하다. reactive() 함수는 함수 내 위젯값 변화가 있는 경우만 실행하게 된다. 주의할 점은 reactive()로 구현할 경우 할당된 변수는 함수 형태로 호출을 한다.

1
2
3
4
output$plot <- renderPlot({
  chartSeries(dataInput(), theme = chartTheme("white"),
    type = "line", log.scale = input$log, TA = NULL)
})

위 예제처럼 dataInput이 아닌 dataInput()과 같은 행태로 호출한다.

전체 코드는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# Load packages ----
library(shiny)
library(bslib)
library(quantmod)

# Source helpers ----
source("helpers.R")

# User interface ----
ui <- page_sidebar(
  title = "stockVis",
  sidebar = sidebar(
    helpText(
      "Select a stock to examine.

        Information will be collected from Yahoo finance."
    ),
    textInput("symb", "Symbol", "SPY"),
    dateRangeInput(
      "dates",
      "Date range",
      start = "2013-01-01",
      end = as.character(Sys.Date())
    ),
    br(),
    br(),
    checkboxInput(
      "log",
      "Plot y axis on log scale",
      value = FALSE
    ),
    checkboxInput(
      "adjust",
      "Adjust prices for inflation",
      value = FALSE
    )
  ),
  card(
    card_header("Price over time"),
    plotOutput("plot")
  )
)

# Server logic
server <- function(input, output) {
  
  output$plot <- renderPlot({
    dataInput <- reactive({
      getSymbols(input$symb, src = "yahoo",
                 from = input$dates[1],
                 to = input$dates[2],
                 auto.assign = FALSE)
    })
    
    finalInput <- reactive({
      if (!input$adjust) return(dataInput())
      adjust(dataInput())
    })
    
    output$plot <- renderPlot({
      chartSeries(finalInput(), theme = chartTheme("white"),
                  type = "line", log.scale = input$log, TA = NULL)
    })
  })
  
}

# Run the app
shinyApp(ui, server)

실행화면

참고자료

  • https://shiny.posit.co/r/getstarted/shiny-basics/lesson6/

_EOF_

This post is licensed under CC BY 4.0 by the author.