使用 sqldf 以相反的顺序应用 Instr 函数

Applying Instr function in reverse order using sqldf

我有这个数据

           Quiz_answers
1 `a1,a5,a2,a3`Positive
2    `a1,a2,a4`Negative
3 `a1,aa4,a2,a3`Neutral
4    `a1,a2,a4`Positive
5    `a1,a2,a4`Negative
6    `a1,a2,a3`Negative
7     `a1,a7,a3`Neutral
8    `a1,a2,a5`Negative

在列 Quiz_Answer 上,当尝试通过将 -1 参数传递给 INSTR 来提取最后一个反引号字符后的字符串时,出现错误: 错误的函数参数数instr().
我可以在不使用 -1 作为参数的情况下 运行 它,但默认情况下它会从头开始搜索。

Quiz_answers<-c("`a1,a5,a2,a3`Positive","`a1,a2,a4`Negative","`a1,aa4,a2,a3`Neutral","`a1,a2,a4`Positive","`a1,a2,a4`Negative","`a1,a2,a3`Negative","`a1,a7,a3`Neutral","`a1,a2,a5`Negative")
data<-data.frame(Quiz_answers);
qr<-sqldf("SELECT substr(Quiz_answers, instr(Quiz_answers,'`',-1) + 1) AS HistoryAnswer from data")

我们可以使用sub来匹配字符串开头的反引号后接零个或多个非反引号后跟反引号的字符,并将其替换为空白("")

sub("^`[^`]*`", "", data$Quiz_answers)
#[1] "Positive" "Negative" "Neutral"  "Positive" "Negative" "Negative" "Neutral"  "Negative"

在实践中,我可能会接受@akrun 给出的答案,但这里有一个应该适用于 Oracle 的查询

SELECT
    REGEXP_REPLACE (Quiz_answers, '`.*`', '')
FROM data

或者在 R 代码中:

qr <- sqldf("REGEXP_REPLACE (Quiz_answers, '`.*`', '') FROM data")

这是一个演示,显示上述查询正常工作:

Demo

1) H2 backend 如果你使用H2 database backend to sqldf那么问题中的select语句将如问题中所写的那样工作:

library(sqldf)
library(RH2)  # if H2 database is loaded sqldf will notice it and use it

sqldf("SELECT 
         substr(Quiz_answers, instr(Quiz_answers,'`',-1) + 1) AS HistoryAnswer 
       FROM data")

1a) H2 还支持 select 语句中的 regexp_replace and regexp_like 函数。

2) SQLite 后端 如果您将默认的 SQLite 后端用于 sqldf,则 trim 关闭左起第一个反引号,在这种情况下,原始的第二个反引号变为第一个,我们可以使用 instr。 (或者我们可以使用 substr(Quiz_answers, 2) 代替 ltrim(...) 。)

library(sqldf)  # if no other database is loaded sqldf uses the RSQLite backend

sqldf("SELECT 
         substr(Quiz_answers, instr(ltrim(Quiz_answers, '`'), '`') + 2) AS HistoryAnswers
       from data")

2a) 如果反引号之间的部分仅包含 a、数字、逗号和反引号,则替代方案如下

sqldf("select ltrim(Quiz_answers, '`a1234567890,') as HistoryAnswers from data")

(如果实际上它可以包含任何字母但不能包含大写字母,那么如果您将 a 替换为 ltrim 第二个参数中的所有字母,它仍然可以工作。)

2b) SQLite 的另一种方法是:

sqldf("select 
    case
      when Quiz_answers like '%Positive' then 'Positive'
      when Quiz_answers like '%Negative' then 'Negative'
      else 'Neutral'
    end as HistoryAnswers 
  from data")

这也适用于 H2。

2c) 或者如果可以 return +1、0、-1 而不是正面、中性、负面则:

sqldf("select 
    (Quiz_answers like '%Positive') - (Quiz_answers like '%Negative') as HistoryAnswers 
  from data")

如果我们将两个布尔值转换为 int,这将在 H2 中起作用。

2d) 另一种方法是使用 reverse 反转字符串,如下所示:

sqldf("select 
   substr(Quiz_answers, length(Quiz_answers) - instr(reverse(Quiz_answers), '`') + 2) 
      as HistoryAnswers 
  from data")