我在R中有一个字符串列表,如下所示:
"A(123:456)"
"B(23456:345)"
"C(3451:45600)"
我想解析所有这些项目的括号中的第一个数字和第二个数字:
first second
123 456
23456 345
3451 45600
以矢量化方式执行此操作的最佳方法是什么?我曾经想过使用子串和索引,但后来听说过正则表达式,但我想知道最多" R"这样做的方法。
答案 0 :(得分:4)
您可以使用regexpr
来匹配模式,
并regmatches
提取匹配的模式。
您可以将要匹配(要提取)的模式定义为\\d+
,这意味着一个或多个数字。
这将匹配每个模式中出现的前3位数。
并使用regmatches
提取匹配项,如下所示:
v <- c("A(123:456)", "B(234:345)", "C(345:456)")
regmatches(v, regexpr('\\d+', v))
上面将给出一个值向量:
[1] "123" "234" "345"
要获得包含两列数值的data.frame
,
您可以使用gregmatches
代替regmatches
。
返回列表列表,
您可以从中将值提取到向量中:
m <- regmatches(v, gregexpr('\\d+', v))
first <- sapply(m, function(x) x[[1]])
second <- sapply(m, function(x) x[[2]])
或者在评论中指出@RuiBarradas,您可以像这样简化sapply
次调用:
first <- sapply(m, '[[', 1)
second <- sapply(m, '[[', 2)
答案 1 :(得分:1)
这是正则表达式的一种方式:
# Your data
df <- data.frame(obs=c("A(123:456)","B(234:345)","C(345:456)"))
# extraction:
df$first <- gsub(df$obs,pattern="^.*\\((.*)\\:.*$",replacement="\\1")
答案 2 :(得分:1)
这有两种方式
第一个是最简单的,如果你的字符串总是正好有两个字符后面跟着三位数的兴趣,它就会起作用。
第二个使用正则表达式。
substr(x, 3, 5)
[1] "123" "234" "345"
sub("^.*\\(([[:digit:]]*).*", "\\1", x)
[1] "123" "234" "345"
然后,如果您想要数字结果,请使用as.integer
或as.numeric
。
数据。强>
x <- scan(what = character(), text = '
"A(123:456)"
"B(234:345)"
"C(345:456)"')
修改强>
在OP编辑问题后,上述解决方案不再有效。以下是。请注意,正则表达式已更改,我现在也使用strsplit
。
res <- do.call(rbind, strsplit(sub("^.*\\((.*)\\).*$", "\\1", x), ":"))
res <- as.data.frame(res, stringsAsFactors = FALSE)
names(res) <- c("first", "second")
res
# first second
#1 123 456
#2 234 345
#3 345 456
此数据框的列都是类character
。为了得到数字,用
res[] <- lapply(res, as.integer)