从 R 中具有多个数字的字符串中提取给定符号后的第一个数字(带小数点)

Extract the first number (with decimals) after a given symbol from a string with multiple numbers in R

我正在尝试从字符串中获取数字(包括小数)。 我的数据是这样的:

V <- c("7.20-<7.35","25-<32","60-<83e","40-<50","0.85-<1.15","80-<98","3.0-<3.4","NA","3.0-<3.4 (110)")

其中数字与字母和符号混合。 我需要提取 < 符号后的第一个数字,同时保留缺失值的索引。 我的输出看起来像:

desired.output <- c(7.35, 32, 83, 50, 1.15, 98, 3.4, NA, 3.4)

我试过:

resp <- as.numeric(unlist(regmatches(V,
                 gregexpr("[[:digit:]]+\.*[[:digit:]]*",V))))
    

resp <-  sub(".*<(^[^-])", "\1", V)

子函数中还有另一个模式,但似乎没有任何效果。

您认为最好的方法是什么?

您可以使用

sub(".*<(\d+(?:\.\d+)?).*", "\1", V, perl=TRUE)
# => [1] "7.35" "32"   "83"   "50"   "1.15" "98"   "3.4"  "NA"   "3.4" 

online R demo and the regex demo。如果您还需要获得像 .05 这样的数字,请将 \d+(?:\.\d+)? 替换为 \d*\.?\d+。如果您还需要获得负数,请在第一个 \d+ 之前附加 -?

详情:

  • .* - 除换行字符外的任何零个或多个字符,尽可能多
  • < - 一个 < 字符
  • (\d+(?:\.\d+)?) - 第 1 组(从替换模式中引用 </code>):一位或多位数字后跟可选的点序列和一位或多位数字</li> <li><code>.* - 除换行字符外的任何零个或多个字符,尽可能多

您还可以指定第一个数字,后跟 -< 并使用可选的小数捕获第二部分。

\d+(?:\.\d+)?-<(\d+(?:\.\d+)?).*

模式匹配:

  • \d+(?:\.\d+)? 匹配 1+ 个带可选小数部分的数字
  • -<字面匹配
  • ( 捕获 组 1
    • \d+(?:\.\d+)? 匹配 1+ 个带可选小数部分的数字
  • ) 关闭组 1
  • .* 匹配行的其余部分

Regex demo

然后你可以匹配结果中不需要的字符串的其余部分,并替换为第1组。

V <- c("7.20-<7.35","25-<32","60-<83e","40-<50","0.85-<1.15","80-<98","3.0-<3.4","NA","3.0-<3.4 (110)")
sub("\d+(?:\.\d+)?-<(\d+(?:\.\d+)?).*", "\1", V)

输出

[1] "7.35" "32"   "83"   "50"   "1.15" "98"   "3.4"  "NA"   "3.4" 

匹配 - <> 的所有变体,您可以使用字符 class 列出所有允许的字符并重复它们 1 次或多次:

sub("\d+(?:\.\d+)?[<>-]+(\d+(?:\.\d+)?).*", "\1", V)

Regex demo

使用 tidyverse 中 stringr 包中的 str_extract

library(tidyverse)
V <- c("7.20-<7.35","25-<32","60-<83e","40-<50","0.85-<1.15","80-<98","3.0-<3.4","NA","3.0-<3.4 (110)")
str_extract(V, "((?<=\<)\d\.?\d+|NA)") %>% 
      as.numeric()

[1]  7.35 32.00 83.00 50.00  1.15 98.00  3.40    NA  3.40