R 如何在Shining中向被动数据表添加注释

R 如何在Shining中向被动数据表添加注释,r,shiny,R,Shiny,这个问题是我发布的问题的延伸: 我创建了一个包含3列的数据框:num、id和val。我希望我的闪亮应用程序执行以下操作: 数据帧dat按num列过滤 从dat的id列中选择一个值(选择输入) 在文本框中添加文本注释(文本输入) 点击一个动作按钮 在数据表中创建一个名为comment的新列,文本注释添加到行中的comment列,其中id等于所选值 代码如下。我不明白为什么它不起作用 提前多谢 library(shiny) library(DT) dat = data.fra

这个问题是我发布的问题的延伸:

我创建了一个包含3列的数据框:num、id和val。我希望我的闪亮应用程序执行以下操作:

  • 数据帧
    dat
    按num列过滤
  • dat
    的id列中选择一个值(选择输入)
  • 在文本框中添加文本注释(文本输入)
  • 点击一个动作按钮
  • 在数据表中创建一个名为comment的新列,文本注释添加到行中的comment列,其中id等于所选值
  • 代码如下。我不明白为什么它不起作用

    提前多谢

        library(shiny)
        library(DT)
        dat = data.frame(num=rep(1:2, each=5), id=rep(LETTERS[1:5],2), val=rnorm(10)) 
        ui = fluidPage(
            fluidRow(
                column(12, selectInput('selectNum', label='Select Num', 
                                     choices=1:10, selected='')),
                column(2, selectInput(inputId = 'selectID',
                                      label = 'Select ID2',
                                      choices = LETTERS[1:10],
                                      selected='',
                                      multiple=TRUE)),
                column(6, textInput(inputId = 'comment', 
                                    label ='Please add comment in the text box:', 
                                    value = "", width = NULL,
                                    placeholder = NULL)),
                column(2, actionButton(inputId = "button", 
                                       label = "Add Comment"))
            ),
            fluidRow (
                column(12, DT::dataTableOutput('data') ) 
            )           
        )
    
        server <- function(input, output, session) {
    
         ## make df reactive
    
         df = reactive ({ dat %>% filter(num %in% input$selectNum) })
         df_current <- reactiveVal(df())
    
         observeEvent(input$button, {
    
          req(df_current())
    
          ## update df by adding comments
          df_new <- df_current()
          df_new[df_current()$id %in% input$selectID, "Comment"] <- input$comment
    
          df_current(df_new)
    
          })
    
          output$data <- DT::renderDataTable({
    
          req(df_current())
    
          DT::datatable(df_current(), 
              options = list(orderClasses = TRUE,
                  lengthMenu = c(5, 10, 20), pageLength = 5))
         })
    
        shinyApp(ui=ui, server=server)
    
    库(闪亮)
    图书馆(DT)
    dat=data.frame(num=rep(1:2,每个=5),id=rep(字母[1:5],2),val=rnorm(10))
    ui=fluidPage(
    fluidRow(
    列(12,selectInput('selectNum',label='selectNum',
    选择数=1:10,选定数=“”),
    第(2)列,选择输入(inputId='selectID',
    标签='选择ID2',
    选择=字母[1:10],
    选定=“”,
    多重=真),
    第(6)列,textInput(inputId='comment',
    label='Please在文本框中添加注释:',
    值=”,宽度=空,
    占位符=空),
    列(2,actionButton)(inputId=“button”,
    label=“添加注释”))
    ),
    fluidRow(
    列(12,DT::dataTableOutput('data'))
    )           
    )
    服务器%filter(在%input$selectNum中的num%})
    
    df_current这里有一个工作示例

    我认为问题在于,您试图通过一个observeEvent更新一个值,而根据文档,这个值并不好?敏锐的

    无论何时,只要您想执行响应事件的操作,都可以使用ObserveeEvent。(请注意,“重新计算值”通常不算作执行操作–请参阅EventResponsive。)

    库(闪亮)
    图书馆(DT)
    dat=data.frame(num=1:10,id=LETTERS[1:10],val=rnorm(10))
    ui=fluidPage(
    fluidRow(
    列(12,selectInput('selectNum',label='selectNum',
    选择数=1:10,选定数=“”),
    第(2)列,选择输入(inputId='selectID',
    标签='选择ID2',
    选择=字母[1:10],
    选定=“”,
    多重=真),
    第(6)列,textInput(inputId='comment',
    label='Please在文本框中添加注释:',
    值=”,宽度=空,
    占位符=空),
    列(2,actionButton)(inputId=“button”,
    label=“添加注释”))
    ),
    fluidRow(
    列(12,DT::dataTableOutput('data'))
    )           
    )
    服务器%filter(在%input$selectNum中为num%)
    如果(输入$按钮!=0){
    输入$按钮
    
    df[df$id%在%input$selectID中,“注释”]对于
    df
    ,使用reactiveVal对象来跟踪
    Comment
    列中以前输入的注释可能比使用reactiveVal对象来跟踪
    df
    更为自然。另请参见对该问题的回答:。如果您更愿意使用reactive/eventReactive语句来跟踪
    df
    最好使用单独的对象来存储以前的输入注释(而不是将其合并到
    df
    的被动语句中)


    非常感谢!您的代码适用于此示例。在我的工作中,Shinny中的原始数据是“反应式”的,因为我根据用户的需要导入不同数量的文件。因此,是否有任何方法可以使用
    df()
    此添加注释函数?
    df()
    实际上在我的应用程序中的其他几个选项卡中使用。我们无法执行
    reactiveVal(df())…
    ?@Joris ChauI使用带有
    df\u current的reactive表达式编辑响应。非常感谢!这是我需要的。
    
    library(shiny)
    library(DT)
    dat = data.frame(num=1:10, id=LETTERS[1:10], val=rnorm(10)) 
    ui = fluidPage(
      fluidRow(
        column(12, selectInput('selectNum', label='Select Num', 
                               choices=1:10, selected='')),
        column(2, selectInput(inputId = 'selectID',
                              label = 'Select ID2',
                              choices = LETTERS[1:10],
                              selected='',
                              multiple=TRUE)),
        column(6, textInput(inputId = 'comment', 
                            label ='Please add comment in the text box:', 
                            value = "", width = NULL,
                            placeholder = NULL)),
        column(2, actionButton(inputId = "button", 
                               label = "Add Comment"))
      ),
      fluidRow (
        column(12, DT::dataTableOutput('data') ) 
      )           
    )
    
    server <- function(input, output, session) {
    
      ## make df reactive
    
      df_current = reactive({ 
        df = dat %>% filter(num %in% input$selectNum) 
    
        if(input$button != 0) {
          input$button    
          df[df$id %in% input$selectID, "Comment"] <- isolate(input$comment)
        }
    
        return(df)
        })
    
    
      output$data <- DT::renderDataTable({
    
        req(df_current())
        DT::datatable(df_current(), 
                      options = list(orderClasses = TRUE,
                                     lengthMenu = c(5, 10, 20), pageLength = 5))
      })
    }
      shinyApp(ui=ui, server=server)
    
    library(shiny)
    library(DT)
    dat = data.frame(num=1:10, id=LETTERS[1:10], val=rnorm(10)) 
    ui = fluidPage(
        fluidRow(
            column(12, selectInput('selectNum', label='Select Num', 
                    choices=1:10)),
            column(2, selectInput(inputId = 'selectID',
                    label = 'Select ID2',
                    choices = LETTERS[1:10],
                    selected='',
                    multiple=TRUE)),
            column(6, textInput(inputId = 'comment', 
                    label ='Please add comment in the text box:', 
                    value = "", width = NULL,
                    placeholder = NULL)),
            column(2, actionButton(inputId = "button", 
                    label = "Add Comment"))
        ),
        fluidRow (
            column(12, DT::dataTableOutput('data') ) 
        )            
    )
    
    server <- function(input, output, session) {
    
      ## make df reactive
      df_current <- reactiveVal(dat)
    
      observeEvent(input$button, {
    
            req(df_current(), input$selectID %in% dat$id)
    
            ## update df by adding comments
            df_new <- df_current()
            df_new[df_current()$id %in% input$selectID, "Comment"] <- input$comment
    
            df_current(df_new)
    
          })
    
      output$data <- DT::renderDataTable({
    
            req(df_current())
    
            ## filter df_current by 'selectNum'
            df_filtered <- df_current()[df_current()$num %in% input$selectNum, ]
    
            ## show comments if non-empty
            showComments <- is.null(df_filtered$Comment) || !all(is.na(df_filtered$Comment))
    
            DT::datatable(df_filtered, 
                options = list(orderClasses = TRUE,
                    lengthMenu = c(5, 10, 20), pageLength = 5,
                    columnDefs = list(
                        list(targets = ncol(df_filtered), visible = showComments)
                    )
                )
            )
    
          })
    }
    
    shinyApp(ui=ui, server=server)
    
    server <- function(input, output, session) {
    
      ## initialize separate reactive object for comments
      df_comments <- reactiveVal({
            data.frame(
                id = character(0), 
                Comment = character(0),
                stringsAsFactors = FALSE
            )
          })
    
      ## reactive object df
      df_current <- reactive({
    
            ## reactivity that df depends on
            ## currently df = dat does not change
            df <- dat
    
            ## merge with current comments
            if(nrow(df_comments()) > 0)
            df <- merge(df, df_comments(), by = "id", all.x = TRUE)
    
            return(df)
    
          })
    
      observeEvent(input$button, {
    
            req(input$selectID)
    
            ## update df_comments by adding comments
            df_comments_new <- rbind(df_comments(), 
                data.frame(id = input$selectID, Comment = input$comment)
            )
    
            ## if duplicated id's keep only most recent rows 
            df_comments_new <- df_comments_new[!duplicated(df_comments_new$id, fromLast = TRUE), , drop = FALSE]
    
            df_comments(df_comments_new)
    
          })
    
      output$data <- DT::renderDataTable({
    
            req(df_current())
    
            ## filter df_current by 'selectNum'
            df_filtered <- df_current()[df_current()$num %in% input$selectNum, ]
    
            ## show comments if non-empty
            showComments <- is.null(df_filtered$Comment) || !all(is.na(df_filtered$Comment))
    
            DT::datatable(df_filtered, 
                options = list(orderClasses = TRUE,
                    lengthMenu = c(5, 10, 20), pageLength = 5,
                    columnDefs = list(
                        list(targets = ncol(df_filtered), visible = showComments)
                    )
                )
            )
    
          })
    }