【问题标题】:Replace parts of a string in R在R中替换字符串的一部分
【发布时间】:2020-07-28 01:33:40
【问题描述】:

我希望能够将keywordN 下方的输入中的tiab LIKE '%keywordN%' 替换为能够将关键字输入转换为R 中的SQL 字符串。关键字是单词或单词组合,例如:@987654323 @

input = "((keyword1) OR (keyword2) AND (keyword3))"

到:

output = "((tiab LIKE '%keyword1%') OR (tiab LIKE '%keyword2%') AND (tiab like '%keyword3%'))"

这样使用:

sqlDF = sqldf(paste("select * from df1 where ",output))

有什么建议吗?非常感谢!

【问题讨论】:

  • 你是如何产生你的“输入”的?
  • input 是从闪亮应用程序中的查询输入传递的。我们要求用户使用语法(即:关键字组周围的括号)
  • 而且总是同一列? “AND”“OR”条件怎么样?

标签: r regex stringr sqldf


【解决方案1】:

sqldf 包为此目的加载 gsubfn 包,因此不需要额外的包。此外,问题中显示的sqldf 语句中使用的paste 也不需要,因为gsubfn 为此提供了fn$,如下所示。

gsubfn 匹配正则表达式,将捕获组传递给第二个参数(这是一个可选的用公式表示法表示的函数,就像我们在这里所做的那样),并用函数的输出替换匹配。我们假设关键字由字母、数字和空格组成,因此我们使用字符类 [A-Za-z0-9 ] 来定义关键字中的有效字符,但如果它们可以包含其他字符,则添加这些字符。

下面我们得到一个错误只是因为问题没有定义示例DF,但它仍然显示传递给后端的扩展 SQL 语句,因此我们可以看到它有效。

library(sqldf)  # sqldf also load gsubfn
input <- "((ELISA) OR (antibody test) AND (blood))"

output <- gsubfn("\\(([A-Za-z0-9 ]+)\\)", ~ sprintf("(tiab LIKE '%%%s%%')", x), input) 

fn$sqldf("select * from DF where $output", verbose = TRUE)

给予:

sqldf: library(RSQLite)
sqldf: m <- dbDriver("SQLite")
sqldf: connection <- dbConnect(m, dbname = ":memory:")
sqldf: initExtension(connection)
sqldf: dbGetQuery(connection, 'select * from DF where ((tiab LIKE '%ELISA%') OR (tiab LIKE '%antibody test%') AND (tiab LIKE '%blood%'))')
Error: no such table: DF
sqldf: dbDisconnect(connection)

【讨论】:

  • 刚刚注意到其他问题下有关特定示例的评论,因此修改了代码以使其能够处理。
  • 感谢您的加入。我认为这将是在 R 中执行关键字搜索选项的最快解决方案,它允许布尔值和嵌套。似乎工作。
【解决方案2】:

使用stringr:

stringr::str_replace_all(input, "keyword(\\d)", "tiab LIKE '%keyword\\1%'")

# "((tiab LIKE '%keyword1%') OR (tiab LIKE '%keyword2%') AND (tiab LIKE '%keyword3%'))"

对于你的另一个例子:

input <- "((ELISA) OR (antibody test) AND (blood))"

str_replace_all(input, "\\(([^\\(\\)]+)\\)", "(tiab LIKE '%\\1%')")

# "((tiab LIKE '%ELISA%') OR (tiab LIKE '%antibody test%') AND (tiab LIKE '%blood%'))"

【讨论】:

  • 亲爱的巴斯,谢谢。但是,我希望有一个通用的解决方案,例如也适用于((ELISA) OR (antibody test) AND (blood))。我将问题更新为更明确。
  • 优秀的基础。感谢您为我节省了很多时间! en een fijne dag!
【解决方案3】:

这个怎么样?

s <- "((ELISA) OR (antibody test) AND (blood))"
gsub("(?<=\\()([^()]*)(?=\\))", "tiab LIKE '%\\1%'", s, perl=T)
# [1] "((tiab LIKE '%ELISA%') OR (tiab LIKE '%antibody test%') AND (tiab LIKE '%blood%'))"

【讨论】:

    猜你喜欢
    • 2021-03-01
    • 2018-12-18
    • 2022-07-18
    • 2023-02-16
    • 2023-03-20
    • 2016-09-14
    • 1970-01-01
    • 2012-05-18
    • 2017-09-19
    相关资源
    最近更新 更多