如何使用Shiny中的重新加载数据来反应性更新数据表?

时间:2019-05-06 15:50:09

标签: r shiny reactive

我想创建一个显示反应式表格的闪亮应用程序。我希望能够同时排除某些行,并将排除的行保存在服务器上的.Rda文件中。关键是要永久排除某些行,因此每次有人加载闪亮的应用程序时,这些行都将被排除。

我已经完成了95%的工作-我闪亮的应用程序显示了表格并将排除的行保存在服务器上的.Rda文件中。重新启动应用程序时,将排除正确的行,但是无法在同一会话中排除表的同时动态排除行。基本上,我希望能够按下操作按钮并立即排除行。

这是闪亮的应用程序

from random import randint

hand_play, die_count_play = [0] * 5, [0] * 6
hand_comp, die_count_comp = [0] * 5, [0] * 6

# The work done in your three loops can be done in one for-loop.
for i in range(5):
    hand_play[i], hand_comp[i] = randint(1,6), randint(1,6)
    die_count_play[hand_play[i]-1] += 1
    die_count_comp[hand_comp[i]-1] += 1


# Put the rankings in a dictionary with tuples corresponding to hands as keys.
rank_dict = {                 (5,):8, # five of a kind
                              (4,):7, # four of a kind
                            (2, 3):6, # full house
                (0, 1, 1, 1, 1, 1):5, # high straight
                (1, 1, 1, 1, 1, 0):4, # low straight
                              (3,):3, # three of a kind
                            (2, 2):2, # two pairs
                              (2,):1  # one pair
              }

def rank_hand(die_count, rank_dict = rank_dict):
    """
    Take in list (length == 6) where each element is a count of the number of 
    times the digits 1-6 occur in throw of 5 dice. Return a hand ranking using 
    a dictionary of rankings `rank_dict`.
    """

    # If max value is two then key is either (2, 2) or (2,).
    if max(die_count) == 2:
        rank = rank_dict[tuple([c for c in die_count if c == 2])]

    # If max value is 1 then hand is either high or low straight, or no hand.
    elif max(die_count) == 1:

        # One of the values, first or last, must be 0 if hand is a high/low 
        # straight. If not, then there's no hand.
        if 0 in die_count[0::5]:
            rank = rank_dict[tuple(die_count)]
        else:
            rank = 0

    # If not a pair, straight, or no hand, then it must be one of remaining 
    # hands.
    else:
        rank = rank_dict[tuple(set([c for c in die_count if c > 1]))]

    return rank


# Call rank_hand on die counts for player and computer.
rank_play = rank_hand(die_count_play)
rank_comp = rank_hand(die_count_comp)

print(f"Player's rank:   {rank_play}\n" +
      f"Player's hand:   {hand_play}\n" + 
      f"Die count:       {die_count_play}\n" + 30*"-"
      )

print(f"Computer's rank: {rank_comp}\n" +
      f"Computer's hand: {hand_comp}\n" + 
      f"Die Count:       {die_count_comp}"
      )

同样,我希望能够1.在会话期间从显示的表中排除行(即,按操作按钮并删除行),并2.保存排除的行以供将来排除。我的代码处理第二部分,但是它不会在我的会话期间排除行(仅在重新加载时)。

1 个答案:

答案 0 :(得分:0)

好的,我知道了!我需要将prev_exclude数据帧存储到reactiveValues对象中。

这是可行的示例

library(shiny)
library(tidyverse)

ui <- fluidPage(

  mainPanel(
    DT::dataTableOutput("flag"),
    actionButton("exclude", "Exclude")

  )
)

server <- function(input, output) {

  df <- data.frame(id = 1:10, fu_score = 1:10,
                   stringsAsFactors = FALSE)

  if (file.exists("data/prev_exclude.Rda")) {
    load("data/prev_exclude.Rda")
  } else {

    prev_exclude <- data.frame(id = 0, fu_score = 0, stringsAsFactors = FALSE)
    save(prev_exclude, file = "data/prev_exclude.Rda")

  }

  prev_exclude_reactive <- reactiveValues(rv = prev_exclude)

  df_flag <- reactive({ 
    df %>%
      anti_join(., prev_exclude_reactive$rv, by = c("id", "fu_score"))
  })

  output$flag <- DT::renderDataTable({
    DT::datatable(df_flag(), options = list(paging = FALSE))
  })

  selected_prev <- eventReactive(input$flag_rows_selected, {
    data.frame(id = df_flag()$id[c(input$flag_rows_selected)],
               fu_score = df_flag()$fu_score[c(input$flag_rows_selected)])

  })

  observeEvent(input$exclude, {

    prev_exclude <- isolate(bind_rows(selected_prev(), prev_exclude_reactive$rv))
    save(prev_exclude, file="data/prev_exclude.Rda")
    load("data/prev_exclude.Rda")

    prev_exclude_reactive$rv <- prev_exclude

  })
}

# Run the application 
shinyApp(ui = ui, server = server)

希望其他人发现并发现它有用。