【问题标题】:Pass user input vector to a function that takes a string将用户输入向量传递给接受字符串的函数
【发布时间】:2018-05-02 15:43:43
【问题描述】:

我有一个接收用户输入的闪亮应用: input$libraries 是由来自

的用户输入产生的反应性字符向量
output$libraries <- renderUI({
checkboxGroupInput(inputId = "libraries", 
                   label = strong("Select the libraries for which you would like to see part counts"), 
                   choiceValues = LibraryIDs$libraryid,
                   choiceNames = LibraryNames$name, 
                   selected = LibraryIDs$libraryid[1],
                   inline = T)}})
})

我想从我的 postgreSQL 数据库中进行选择,我设置了一个函数:

get_query <- function(querystring){
  # create a connection

  # loads the PostgreSQL driver
  drv <- dbDriver("PostgreSQL")
  con <- dbConnect(drv, dbname = "RosettaRelational",
                   host = "localhost", port = 5432,
                   user = "postgres", password = rstudioapi::askForPassword("Database password"))
  on.exit(dbDisconnect(con))

  # check for the existance of tables, must be created in pgAdmin4
  #dbExistsTable(con, "libraries")

  query <- eval(parse(text = querystring))
  return(query)
}

它接受一个字符串并对其进行解析以评估查询

现在当我尝试这样查询数据库时:

Names <- get_query(paste0("con %>% tbl('libraries') %>% 
filter(libraryid %in% input$libraries) %>% select(name) %>% collect()"))

我收到错误:找不到对象“输入”。我知道它没有正确解析反应字符向量。我应该如何更改它才能使其正常工作?

我试过了:

Names <- get_query(paste0("con %>% tbl('libraries') %>% 
filter(libraryid %in% '",input$libraries,"') %>% select(name) %>% collect()"))

但即使用户选择了多个库,它也只会选择向量中的第一个库。当 input$ 仅是一个字符时,例如当输入是操作按钮而不是复选框时,此方法有效

基本上,如果用户选择 111a、111b、211 和 311a,我需要将 input$libraries 传递到字符串中时看起来像 c('111a,'111b','211','311a'),而不是目前正在传递的“111a”。

【问题讨论】:

    标签: r postgresql shiny


    【解决方案1】:

    从我这边的一些测试看来,您的代码

    Names <- get_query(paste0("con %>% tbl('libraries') %>% filter(libraryid %in% '",input$libraries,"') %>% select(name) %>% collect()"))
    

    将以当前形式“矢量化”input$libraries 中的多个库。这将为 input$libraries 中的每个库创建一个单独的字符串,而不是一个包含所有库的字符串。例如

    > Names
    [1] "con %>% tbl('libraries') %>% filter(libraryid %in% '111a') %>% select(name) %>% collect()" 
    [2] "con %>% tbl('libraries') %>% filter(libraryid %in% '111b') %>% select(name) %>% collect()"
    

    使用我自己的数据和您的建议“让input$libraries 看起来像 c('111a','111b','211','311a')”我将您的代码修改为

    Names <- get_query(paste0("con %>% tbl('libraries') %>% filter(libraryid %in% c(", paste0("'", input$libraries, "'", collapse = ", "), ")) %>% select(name) %>% collect()"))
    

    这应该会为您提供所需的 c('111a', '111b', '211', '311a')。

    这不是最优雅的,但它应该可以工作。如果它看起来很乱,你也可以在paste0()之前这样做,如下所示

    libraries_comma_separated <- paste0("'", input$libraries, "'", collapse = ", ")
    

    这会给你'111a','111b','211','311a'然后做

    Names <- get_query(paste0("con %>% tbl('libraries') %>% filter(libraryid %in% c(", libraries_comma_separated, ")) %>% select(name) %>% collect()"))
    

    【讨论】:

    • 我太接近了!我已经想出了如何让它看起来像 c('111a, '111b', '211', '311a'),但可能是因为某个地方的简单语法错误,它在传递给字符串时仍然给我一个错误..你所做的工作,也是我的逻辑,但不知何故我没有正确执行..非常感谢!
    • 当然,很高兴能帮上忙。我之前使用过类似的代码,这使它更容易。语法总是能让你受益,而且通常很难调试。
    猜你喜欢
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2017-04-18
    • 2021-08-26
    • 2020-03-15
    • 2018-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多