Удалить элементы до нескольких шаблонов - PullRequest
1 голос
/ 05 ноября 2019

У меня есть данные о странах, например,

MWE <- list("Argentina -2.4 3.4", "Euro area 3.7 6.4")

Я хочу получить список только с цифрами. В моем примере, get "-2.4 3.4" "3.7 6.4" Обратите внимание, что моя "страна" может быть в нескольких словах, поэтому я не могу играть с пробелами так легко, как хотелось бы.

Мне удалось сделать это только сположительные числа с

MWE_1 <- sub("^.*?(\\d)", "\\1",MWE)

Но с отрицательными числами или другими словами, которые также возможны до чисел, мой подход не работает.

Я пытался использовать |, ноне удалось, оба

MWE_2 <- sub("^.*?(\\d)|^.*?(-)", "\\1",MWE)
MWE_3 <- sub("^.*?(\\d|-)", "\\1",MWE)

дают мне один и тот же результат без минус `" 2.4 3.4 "" 3.7 6.4 ".

Если мой MWE равен

MWE <- list("R text1 47 GDP -2.4 3.4", "Euro area but not UK CPI 3.7 6.4")

Iхотите получить весь текст из «ВВП» или «ИПЦ», то есть GDP 2.4 3.4 и CPI 3.7 6.4. Бывает, что

NMWE2 <- sub("^.*?(GDP|CPI)",NMWE)

работает, так что я думаю, это просто вопрос о том, как указать знак минус, хотя экранирование с помощью \\- тоже не работает. `

Ответы [ 4 ]

2 голосов
/ 05 ноября 2019

Вот несколько альтернатив. Все используют только базу R.

1) вставьте запятые вокруг 1-го числового поля Вставьте запятую до и после первого числа, заменяя пробелы, и затем используйте read.table:

read.table(text = sub(" ([-0-9.]+) ", ",\\1,", unlist(MWE)), sep = ",", as.is = TRUE)

, дающий:

         V1   V2  V3
1 Argentina -2.4 3.4
2 Euro area  3.7 6.4

2) Повторный подпункт Альтернативно замените последний пробел запятой дважды.

mwe <- sub("(.*) ", "\\1,", sub("(.*) ", "\\1,", unlist(MWE)))
read.table(text = mwe, sep = ",", as.is = TRUE)

3) strcapture strcapture берет шаблон и помещает каждую группу захвата в столбец:

strcapture("(.*) (.*) (.*)", unlist(MWE), 
  list(V1 = character(0), V2 = numeric(0), V3 = numeric(0)))
1 голос
/ 06 ноября 2019

Другая возможность:

gsub(".*? ([^ ]+ .[^ ]+)","\\1", MWE)
#> [1] "-2.4 3.4" "3.7 6.4" 

Мы сопоставляем последовательность:

  • что угодно (возможно, с пробелами)
  • пробел
  • некоторые непробельные символы
  • еще один пробел
  • еще несколько непробельных символов

И замените его группой, составленной из последних 3.


edit: после прочтения вашего другого вопроса: R удалить элементы на основе нескольких опций , кажется, вы хотите извлечь всю информацию, в этом случае вам может понравиться мой пакет unglue.

# install.packages("unglue")
library(unglue)
MWE <- list("Argentina -2.4 3.4", "Euro area 3.7 6.4")

unglue_data(MWE,"{Country} {numbers=[^ ]+ [^ ]+}")
#>     Country  numbers
#> 1 Argentina -2.4 3.4
#> 2 Euro area  3.7 6.4

unglue_data(MWE,"{Country} {number1=[^ ]+} {number2=[^ ]+}", convert = TRUE)
#>     Country number1 number2
#> 1 Argentina    -2.4     3.4
#> 2 Euro area     3.7     6.4

Создано в 2019-11-06 пакетом Представить (v0.3.0)

Подробнее об этом здесь: https://github.com/moodymudskipper/unglue/blob/master/README.md

1 голос
/ 05 ноября 2019

Вы хотите использовать регулярное выражение PCRE (не забывайте использовать perl=TRUE с (g)sub):

^(?:.*\b(GDP|CPI)\b|.*?([+-]?\d))

См. Демонстрационную версию regex .

Подробности

  • ^ - начало строки
  • (?:.*\b(GDP|CPI)\b|.*?([+-]?\d)) - группа без захвата, соответствующая любой из двух альтернатив:
    • .*\b(GDP|CPI)\b - любой ноль или более символов, кроме символов разрыва строки, как можно больше, вплоть до последнего целого слова GDP или CPI в строке (включается в группу 1, \1)
    • | - или
    • .*?([+-]?\d) - любой ноль или более символов, кроме символов перевода строки, как можно меньше, вплоть до первого необязательного - или +, а затем 1 цифра (заносится в группу2, \2).

R демо :

MWE <- c("R text1 47 GDP -2.4 3.4", "Euro area but not UK CPI 3.7 6.4", "Argentina -2.4 3.4", "Euro area 3.7 6.4")
gsub("^(?:.*\\b(GDP|CPI)\\b|.*?([+-]?\\d))", "\\1\\2", MWE, perl=TRUE)
## => [1] "GDP -2.4 3.4" "CPI 3.7 6.4"  "-2.4 3.4"     "3.7 6.4" 
0 голосов
/ 13 ноября 2019

Если у вас есть формат, всегда заканчивающийся двумя действительными числами, может быть, следующее может сделать работу:

gsub(".*?\\s(\\-?\\d+.*)","\\1",MWE)

, где сопоставление и извлечение начинается с действительного числа (или со знака первого числа)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...