Заменить шаблон строки в sqldf - PullRequest
2 голосов
/ 02 апреля 2019

У меня есть датафрейм, как показано ниже:

    Col1    Col2   Col3
ten: end       5     10
five: nb       7     11
    12:4      12     10
   13:56      15     16

Используя пакет sqldf в R, я хочу сделать следующее:

Заменить значения в Col1 на: character: space с -.У черты есть пробелы в начале и конце.

Заменить значения в Col1 на: number:number на -.У черты нет пробелов в начале и конце.

Ожидаемый результат:

     Col1    Col2   Col3
ten - end       5     10
five - nb       7     11
     12-4      12     10
    13-56      15     16

Вот пример синтаксиса с использованием sqldf:

df <- sqldf("SELECT *, replace([Col1], [character: space], ' - ') [New Col generated] from df")

df <- sqldf("SELECT *, replace([Col1], [number:number], '-') [New Col generated_num] from df")

Я пытался ссылаться на этот документ, но все еще не повезло: https://www.rexegg.com/regex-quickstart.html

1 Ответ

2 голосов
/ 02 апреля 2019

1) Предполагая, что разрешены только формы, указанные в вопросе, замените двоеточия знаками минус, а затем замените минус, а затем пробел пробелом, минус, пробел.

library(sqldf)
sqldf("select *, replace(replace([Col1], ':', '-'), '- ', ' - ') as New from df")

дает:

      Col1 Col2 Col3       New
1 ten: end    5   10 ten - end
2 five: nb    7   11 five - nb
3     12:4   12   10      12-4
4    13:56   15   16     13-56

2) Если мы можем предположить, что единственными формами являются числа: число или символ: символ и что вторая форма не содержит цифр.

sqldf("select *, 
  case when strFilter(Col1, '0123456789') = '' 
         then replace(Col1, ':', ' -')
       else replace(Col1, ':', '-')
       end as New
  from df")

дает:

      Col1 Col2 Col3       New
1 ten: end    5   10 ten - end
2 five: nb    7   11 five - nb
3     12:4   12   10      12-4
4    13:56   15   16     13-56

3) Сначала проверяются цифры: цифры, а затем проверяются символы: символы, где символы могут быть только цифрами или строчными буквами.

dig <- "0123456789"
diglet <- "0123456789abcdefghijklmnopqrstuvwxyz"

fn$sqldf("select *,
  case when trim(Col1, '$dig') = ':'
         then replace(Col1, ':', '-')
  when trim(Col1, '$diglet') = ': '
          then replace(Col1, ': ', ' - ')
  else Col1 end as New
  from df")

дает:

      Col1 Col2 Col3       New
1 ten: end    5   10 ten - end
2 five: nb    7   11 five - nb
3     12:4   12   10      12-4
4    13:56   15   16     13-56

4) Этот извлекает x: y и проверяет, являются ли x и y числами, и если да, то делает ли соответствующую замену, и если нет совпадения, то извлекает x: yz, где y - пробел, и если x и z - цифры или строчные буквы, тогда он выполняет соответствующую замену и в противном случае возвращает Col1. dig и diglet сверху.

fn$sqldf("select *, 
  case when trim(substr(Col1, instr(Col1, ':')-1, 3), '$dig') = ':'
         then replace(Col1, ':', '-')
       when trim(substr(Col1, instr(Col1, ':') -1, 4), '$diglet') = ': '
         then replace(Col1, ': ', ' - ')
       else Col1 end as New
  from df")

Примечание

Вход в воспроизводимой форме:

Lines <- "Col1,Col2,Col3
ten: end,5,10
five: nb,7,11
12:4,12,10
13:56,15,16"
df <- read.csv(text = Lines, as.is = TRUE, strip.white = TRUE)
...