将字符数据拆分为数字和字母

时间:2012-03-18 05:54:35

标签: r

我有一个字符数据向量。矢量中的大多数元素由一个或多个字母后跟一个或多个数字组成。我希望将向量中的每个元素分成字符部分和数字部分。我在Stackoverflow.com上发现了类似的问题:

split a character from a number with multiple digits

然而,上面给出的答案似乎并不完全适用于我的情况或我做错了什么。示例向量如下:

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)

我如何获得角色部分?我在Windows 7 64位计算机上使用R版本2.14.1。

7 个答案:

答案 0 :(得分:18)

对于你的正则表达式,你必须使用:

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

[:digit:]字符类仅在一组[]内有意义。

答案 1 :(得分:17)

使用stringr,如果您愿意(与answer to the other question略有不同):

# 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"

答案 2 :(得分:12)

由于之前的答案都没有使用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])"
           )

答案 3 :(得分:4)

迟到的答案,但另一个选择是使用strsplit一个正则表达式模式,它使用lookarounds来查找数字和字母之间的边界:

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

当前一个字符是字母且后面的字符是数字时,上述模式将匹配(但不消耗),反之亦然。请注意,我们在Perl模式下使用strsplit来访问外观。

Demo

答案 4 :(得分:3)

稍微优雅的方式(没有任何外部包):

> 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"

答案 5 :(得分:0)

您还可以使用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")

答案 6 :(得分:0)

mydata.nub<-gsub("\ \ D","",my.data)

mydata.text<-gsub("\ \ d","",my.data)

这是完美的,即使文本之间有数字,它也将数字和文本分开。