разбить символьные данные на цифры и буквы - PullRequest
17 голосов
/ 18 марта 2012

У меня есть вектор символьных данных.Большинство элементов в векторе состоят из одной или нескольких букв, за которыми следуют одно или несколько чисел.Я хочу разделить каждый элемент вектора на символьную часть и числовую часть.Я нашел похожий вопрос на Stackoverflow.com здесь:

разделить символ из числа с несколькими цифрами

Однако приведенный выше ответ, похоже, не работает полностьюв моем случае или я делаю что-то не так.Ниже приведен пример вектора:

my.data <- c("aaa", "b11", "b21", "b101", "b111", "ccc1", "ddd1", "ccc20", "ddd13")

# I can obtain the number portion using:
gsub("[^[:digit:]]", "", my.data)

# However, I cannot obtaining the character portion using:
gsub("[:digit:]", "", my.data)

Как получить часть символа?Я использую R версии 2.14.1 на 64-битной машине с Windows 7.

Ответы [ 6 ]

18 голосов
/ 18 марта 2012

Для вашего регулярного выражения вы должны использовать:

gsub("[[:digit:]]","",my.data)

Класс [:digit:] имеет смысл только внутри набора [].

17 голосов
/ 18 марта 2012

С stringr, если хотите (и немного отличается от ответа на другой вопрос ):

# load library
library(stringr)
#
# load data
my.data <- c("aaa", "b11", "b21", "b101", "b111", "ccc1", "ddd1", "ccc20", "ddd13")
#
# extract numbers only
my.data.num <- as.numeric(str_extract(my.data, "[0-9]+"))
#
# check output
my.data.num
[1]  NA  11  21 101 111   1   1  20  13
#
# extract characters only
my.data.cha <- (str_extract(my.data, "[aA-zZ]+"))
# 
# check output
my.data.cha
[1] "aaa" "b"   "b"   "b"   "b"   "ccc" "ddd" "ccc" "ddd"
12 голосов
/ 06 декабря 2017

Так как ни один из предыдущих ответов не использует tidyr::separate, здесь идет речь:

library(tidyr)

df <- data.frame(mycol = c("APPLE348744", "BANANA77845", "OATS2647892", "EGG98586456"))

df %>%
  separate(mycol, 
           into = c("text", "num"), 
           sep = "(?<=[A-Za-z])(?=[0-9])"
           )
5 голосов
/ 06 декабря 2017

Поздний ответ, но другой вариант - использовать strsplit с шаблоном регулярных выражений, который использует обходные пути, чтобы найти границу между цифрами и буквами:

var <- "ABC123"
strsplit(var, "(?=[A-Za-z])(?<=[0-9])|(?=[0-9])(?<=[A-Za-z])", perl=TRUE)
[[1]]
[1] "ABC" "123"

Приведенный выше шаблон будет соответствовать (но не потреблять)когда либо предыдущий символ является буквой, а следующий символ является числом, или наоборот.Обратите внимание, что мы используем strsplit в режиме Perl для доступа к поисковым системам.

Демо

5 голосов
/ 27 ноября 2017

Немного более элегантный способ (без каких-либо внешних пакетов):

> x = c("aaa", "b11", "b21", "b101", "b111", "ccc1", "ddd1", "ccc20", "ddd13")
> gsub('\\D','', x)       # replaces non-digits with blancs
[1] ""    "11"  "21"  "101" "111" "1"   "1"   "20"  "13" 
> gsub('\\d','', x)       # replaces digits with blanks
[1] "aaa" "b"   "b"   "b"   "b"   "ccc" "ddd" "ccc" "ddd"
0 голосов
/ 27 ноября 2017

Вы также можете использовать colsplit из reshape2, чтобы разбить ваш вектор на столбцы символов и цифр за один шаг:

library(reshape2)

colsplit(my.data, "(?<=\\p{L})(?=[\\d+$])", c("char", "digit"))

Результат:

  char digit
1  aaa    NA
2    b    11
3    b    21
4    b   101
5    b   111
6  ccc     1
7  ddd     1
8  ccc    20
9  ddd    13

Данные:

my.data <- c("aaa", "b11", "b21", "b101", "b111", "ccc1", "ddd1", "ccc20", "ddd13")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...