R:根据模式删除字符串的第一部分和最后一部分

R: Delete first and last part of string based on pattern

此字符串是债券的代码:OAT 3 25/32 7/17/17。我想提取 3 25/32 的息票利率,读作 3 + 25/323.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