0

我正在创建一个闪亮的筛选应用程序,它允许用户在预定的数据帧上键入 R 命令,例如filter和。mutate

就个人而言,我认为最用户友好的方法是使用包含筛选参数的空白数据框列,用户可以在其中输入命令,例如filter(mpg >= 21)mutate(cyl_sq = cyl^2)使用mtcars数据集作为示例。

显示预期功能的简单应用程序:

library(shiny)
library(shinydashboard)
library(DT)
library(dplyr)
# Header ------------------------------------------------
header <- dashboardHeader(title = "Example Screening")
# Sidebar ------------------------------------------------
sidebar <- dashboardSidebar()
# Body ------------------------------------------------
body <-
dashboardBody(
  fluidRow(
       column(6,h3("Screening Parameters")),
       column(6,h3("Filtered/Modified Results"))),
  fluidRow(
       column(6,DT::dataTableOutput("screening_params")),
       column(6,DT::dataTableOutput("filtered_results")))
)
# APP ------------------------------------------------
shinyApp(ui <- dashboardPage(
  header,
  sidebar,
  body
),
# Server ----------------------------------------------------------
shinyServer(function(input,output){

  output$screening_params <- renderDataTable({
    tibble(params = c("filter(mpg >= 21)",
                      "mutate(cyl_sq = cyl^2)",
                      rep_len(NA_character_,8))) %>%
      DT::datatable(rownames = F,
                    editable = T)
  })

  output$filtered_results <- renderDataTable({
    mtcars %>%
      # input$screening_params
      DT::datatable()

  })

})) 

我愿意使用DTrhandsontable或任何人能想到的替代方案。不幸的是,您似乎无法在 中获取已编辑的表值DT,但希望它为我所追求的提供了一个很好的示例。

我已经尝试了我能想到的所有 quosures 和映射函数的组合,但都无济于事。

有人有想法么?

4

2 回答 2

1

这是一种稍微不同的方法,但也许你会发现它很有用。我sqldf用作 SQL 查询引擎,用户可以使用给定数据集上的临时 SQL 查询来操作数据。如果这不是您所追求的,我至少希望它会给您一些关于如何使用dplyr语法的提示。

如果您仍然选择该dplyr选项并且您有一个带有请求操作的字符串,您可以使用响应式方法getDataset来评估您从用户那里收到的表达式,操作您的数据集。然后调用getDatasetrenderDataTable方法,就像我在附加代码中所做的那样。

评估字符串表达式的示例:

eval(parse(text="res <- mtcars %>% filter(mpg < 20)"))

对于 SQL 选项:

library(shiny)
library(shinydashboard)
library(DT)
library(dplyr)
library(sqldf)
# Header ------------------------------------------------
header <- dashboardHeader(title = "Example Screening")
# Sidebar ------------------------------------------------
sidebar <- dashboardSidebar(collapsed = TRUE)
# Body ------------------------------------------------
body <-
  dashboardBody(
    fluidRow(
      #column(6,h3("Screening Parameters")),
      column(6,h3("Filtered/Modified Results"))),
    fluidRow(
      textInput("sql","SQL Query",value = "SELECT * FROM dataset"),
      DT::dataTableOutput(("filtered_results"))
    )
  )
# APP ------------------------------------------------
shinyApp(ui <- dashboardPage(
  header,
  sidebar,
  body
),
# Server ----------------------------------------------------------
shinyServer(function(input,output){

  ## A new function to load data and perform the SQL query on it
  getDataset <- reactive({
    query <- input$sql
    dataset <- mtcars
    sqldf::sqldf(query)
  })

  output$filtered_results <- renderDataTable({
    getDataset() %>%
      DT::datatable()

  })

})) 
于 2018-12-02T21:02:53.143 回答
0

感谢 Omri374 与我反复交流想法。

满足要求的简单应用程序:

library(shinydashboard)
library(DT)
library(dplyr)
library(rhandsontable)
# Header ------------------------------------------------
header <- dashboardHeader(title = "Example Screening")
# Sidebar ------------------------------------------------
sidebar <- dashboardSidebar()
# Body ------------------------------------------------
body <-
  dashboardBody(
    fluidRow(
      column(6,h3("Screening Parameters")),
      column(6,h3("Filtered/Modified Results"))),
    fluidRow(
      column(6, rHandsontableOutput("hot")),
      column(6, dataTableOutput("filtered_results")))
  )
# APP ------------------------------------------------
shinyApp(ui <- dashboardPage(
  header,
  sidebar,
  body
),
# Server ----------------------------------------------------------
shinyServer(function(input,output){

  output$hot <- renderRHandsontable({
    tibble(params = c("filter(mpg >= 21)",
                      "filter(cyl == 4)",
                      "mutate(cyl_sq = cyl^2)",
                      "select(cyl,mpg,drat)",
                      rep_len(NA_character_,6))) %>%
      rhandsontable() %>%
      hot_cols(colWidths = 500)
  })

  output$filtered_results <- renderDataTable({


    df <- mtcars

    params <- input$hot %>%
      hot_to_r() %>%
      filter(!is.na(params),params != "") %>%
      mutate(params = ifelse(row_number() == max(row_number()),
                             params,
                             paste0(params," %>% "))) %>%
      pull(params) %>%
      str_c(collapse = "")


    if(length(params)>=1){

      eval(parse(text = paste0("filt_df <- df %>%",params)))

    } else {

      filt_df <- df

    }

    filt_df %>%
      datatable()



  })

}))
于 2018-12-03T21:56:13.847 回答