R:根据模式删除字符串的第一部分和最后一部分
R: Delete first and last part of string based on pattern
此字符串是债券的代码:OAT 3 25/32 7/17/17
。我想提取 3 25/32 的息票利率,读作 3 + 25/32
或 3.78125
。现在我一直在尝试用 gsub
删除日期和名称 OAT
,但是我遇到了一些问题。
这是删除日期的代码:
tkr.bond <- 'OAT 3 25/32 7/17/17'
tkr.ptrn <- '[0-9][[:punct:]][0-9][[:punct:]][0-9]'
gsub(tkr.ptrn, "", tkr.bond)
但是它得到了相同的字符串。当我在模式中使用 [0-9][[:punct:]][0-9]
时,我设法删除了部分日期,但它也删除了债券票面利率的小数部分。
棘手的事情是找到一个不涉及优惠券模式的解决方案,因为代码有这种形式:命名优惠券日期,因此,使用优惠券的特定模式可能会限制解决方案的范围.例如,如果代码是这样OAT 0 7/17/17
,优惠券是零。
尝试
eval(parse(text=sub('[A-Z]+ ([0-9]+ )([0-9/]+) .*', '\1 + \2', tkr.bond)))
#[1] 3.78125
或者您可能需要
sub('^[A-Z]+ ([^A-Z]+) [^ ]+$', '\1', tkr.bond)
#[1] "3 25/32"
更新
tkr.bond1 <- c(tkr.bond, 'OAT 0 7/17/17')
v1 <- sub('^[A-Z]+ ([^A-Z]+) [^ ]+$', '\1', tkr.bond1)
unname(sapply(sub(' ', '+', v1), function(x) eval(parse(text=x))))
#[1] 3.78125 0.00000
或
vapply(strsplit(tkr.bond1, ' '), function(x)
eval(parse(text= paste(x[-c(1, length(x))], collapse="+"))), 0)
#[1] 3.78125 0.00000
或没有 eval(parse
vapply(strsplit(gsub('^[^ ]+ | [^ ]+$', '', tkr.bond1), '[ /]'), function(x) {
x1 <- as.numeric(x)
sum(x1[1], x1[2]/x1[3], na.rm=TRUE)}, 0)
#[1] 3.78125 0.00000
类似于 akrun 的回答,使用 sub 替换。它是如何工作的:你把你的 "desired" 模式放在括号里,剩下的放在外面(同时仍然把正则表达式字符匹配那里的和你不想保留的)。然后,当您说 replacement = "\1"
时,您表示整个字符串必须仅由括号内的内容替换。
sub(pattern = ".*\s(\d\s\d+\/\d+)\s.*", replacement = "\1", x = tkr.bond, perl = TRUE)
# [1] "3 25/32"
那你可以改成数值:
temp <- sub(pattern = ".*\s(\d\s\d+\/\d+)\s.*", replacement = "\1", x = tkr.bond, perl = TRUE)
eval(parse(text=sub(" ","+",x = temp)))
# [1] 3.78125
只需用空字符串替换第一个和最后一个单词。
> tkr.bond <- 'OAT 3 25/32 7/17/17'
> gsub("^\S+\s*|\s*\S+$", "", tkr.bond)
[1] "3 25/32"
或
使用gsubfn
函数以便在替换部分使用函数。
> gsubfn("^\S+\s+(\d+)\s+(\d+)/(\d+).*", ~ as.numeric(x) + as.numeric(y)/as.numeric(z), tkr.bond)
[1] "3.78125"
更新:
> tkr.bond1 <- c(tkr.bond, 'OAT 0 7/17/17')
> m <- gsub("^\S+\s*|\s*\S+$", "", tkr.bond1)
> gsubfn(".+", ~ eval(parse(text=x)), gsub("\s+", "+", m))
[1] "3.78125" "0"
这里也可以使用strsplit。然后评估不包括第一个和最后一个的组件。像这样
> tickers <- c('OAT 3 25/32 7/17/17', 'OAT 0 7/17/17')
>
> unlist(lapply(lapply(strsplit(tickers, " "),
+ function(x) {x[-length(x)][-1]}),
+ function(y) {sum(
+ sapply(y, function (z) {eval(parse(text = z))}) )} ) )
[1] 3.78125 0.00000
此字符串是债券的代码:OAT 3 25/32 7/17/17
。我想提取 3 25/32 的息票利率,读作 3 + 25/32
或 3.78125
。现在我一直在尝试用 gsub
删除日期和名称 OAT
,但是我遇到了一些问题。
这是删除日期的代码:
tkr.bond <- 'OAT 3 25/32 7/17/17'
tkr.ptrn <- '[0-9][[:punct:]][0-9][[:punct:]][0-9]'
gsub(tkr.ptrn, "", tkr.bond)
但是它得到了相同的字符串。当我在模式中使用 [0-9][[:punct:]][0-9]
时,我设法删除了部分日期,但它也删除了债券票面利率的小数部分。
棘手的事情是找到一个不涉及优惠券模式的解决方案,因为代码有这种形式:命名优惠券日期,因此,使用优惠券的特定模式可能会限制解决方案的范围.例如,如果代码是这样OAT 0 7/17/17
,优惠券是零。
尝试
eval(parse(text=sub('[A-Z]+ ([0-9]+ )([0-9/]+) .*', '\1 + \2', tkr.bond)))
#[1] 3.78125
或者您可能需要
sub('^[A-Z]+ ([^A-Z]+) [^ ]+$', '\1', tkr.bond)
#[1] "3 25/32"
更新
tkr.bond1 <- c(tkr.bond, 'OAT 0 7/17/17')
v1 <- sub('^[A-Z]+ ([^A-Z]+) [^ ]+$', '\1', tkr.bond1)
unname(sapply(sub(' ', '+', v1), function(x) eval(parse(text=x))))
#[1] 3.78125 0.00000
或
vapply(strsplit(tkr.bond1, ' '), function(x)
eval(parse(text= paste(x[-c(1, length(x))], collapse="+"))), 0)
#[1] 3.78125 0.00000
或没有 eval(parse
vapply(strsplit(gsub('^[^ ]+ | [^ ]+$', '', tkr.bond1), '[ /]'), function(x) {
x1 <- as.numeric(x)
sum(x1[1], x1[2]/x1[3], na.rm=TRUE)}, 0)
#[1] 3.78125 0.00000
类似于 akrun 的回答,使用 sub 替换。它是如何工作的:你把你的 "desired" 模式放在括号里,剩下的放在外面(同时仍然把正则表达式字符匹配那里的和你不想保留的)。然后,当您说 replacement = "\1"
时,您表示整个字符串必须仅由括号内的内容替换。
sub(pattern = ".*\s(\d\s\d+\/\d+)\s.*", replacement = "\1", x = tkr.bond, perl = TRUE)
# [1] "3 25/32"
那你可以改成数值:
temp <- sub(pattern = ".*\s(\d\s\d+\/\d+)\s.*", replacement = "\1", x = tkr.bond, perl = TRUE)
eval(parse(text=sub(" ","+",x = temp)))
# [1] 3.78125
只需用空字符串替换第一个和最后一个单词。
> tkr.bond <- 'OAT 3 25/32 7/17/17'
> gsub("^\S+\s*|\s*\S+$", "", tkr.bond)
[1] "3 25/32"
或
使用gsubfn
函数以便在替换部分使用函数。
> gsubfn("^\S+\s+(\d+)\s+(\d+)/(\d+).*", ~ as.numeric(x) + as.numeric(y)/as.numeric(z), tkr.bond)
[1] "3.78125"
更新:
> tkr.bond1 <- c(tkr.bond, 'OAT 0 7/17/17')
> m <- gsub("^\S+\s*|\s*\S+$", "", tkr.bond1)
> gsubfn(".+", ~ eval(parse(text=x)), gsub("\s+", "+", m))
[1] "3.78125" "0"
这里也可以使用strsplit。然后评估不包括第一个和最后一个的组件。像这样
> tickers <- c('OAT 3 25/32 7/17/17', 'OAT 0 7/17/17')
>
> unlist(lapply(lapply(strsplit(tickers, " "),
+ function(x) {x[-length(x)][-1]}),
+ function(y) {sum(
+ sapply(y, function (z) {eval(parse(text = z))}) )} ) )
[1] 3.78125 0.00000