在 R 中选择字符串的一部分



我有一列字符串,看起来像这样:

 Topology=o5-22i34-56o74-96i117-139o159-181i210-232o247-269i
 Topology=o4-26i35-57o77-99i119-138o161-183i216-238o248-270i
 Topology=o4-21i32-54o69-91i112-134o156-178i215-237o252-271i
 Topology=i20-42o65-84i105-127o158-180i212-234o249-271i     
 Topology=o5-27i39-61o76-98i118-140o151-173i194-213o 

我想得到等号后的第一个数字和字符串中的最后一个数字。 输出应类似于

    5,269
    4,270
    4,271
    20,271
    5,213
v <- c("Topology=o5-22i34-56o74-96i117-139o159-181i210-232o247-269i", 
"Topology=o4-26i35-57o77-99i119-138o161-183i216-238o248-270i", 
"Topology=o4-21i32-54o69-91i112-134o156-178i215-237o252-271i", 
"Topology=i20-42o65-84i105-127o158-180i212-234o249-271i",
"Topology=o5-27i39-61o76-98i118-140o151-173i194-213o") 
sub("^Topology=.(\d+)-.*-(\d+).*$", "\1,\2", v)
# [1] "5,269"  "4,270"  "4,271"  "20,271" "5,213"

r <- regexec("^Topology=.(\d+)-.*-(\d+).*$", v)
m <- regmatches(v, m)
(mat <- do.call(rbind, lapply(m, "[", 2:3)))
#       [,1] [,2] 
# [1,] "5"  "269"
# [2,] "4"  "270"
# [3,] "4"  "271"
# [4,] "20" "271"
# [5,] "5"  "213"

最后,如果你想要数字数据(而不是字符/字符串数据):

apply(mat, 2, as.numeric)
#      [,1] [,2]
# [1,]    5  269
# [2,]    4  270
# [3,]    4  271
# [4,]   20  271
# [5,]    5  213

1)这假设s是一个字符向量,每个组件都有一个这样的字符串。 下面的单行提取所有数字字符串,将每个这样的字符串转换为数字,然后取每行的第一行和最后一行。最后,它将其重塑为一个被转置的矩阵。 fn$sapply允许我们在末尾使用函数的公式表示法:

> library(gsubfn)
> t(fn$sapply(strapply(s, "\d+", as.numeric), ~ c(head(x, 1), tail(x, 1))))
     [,1] [,2]
[1,]    5  269
[2,]    4  270
[3,]    4  271
[4,]   20  271
[5,]    5  213

2)如果我们想要一个逗号分隔字符串的向量,则将其修改为:

> fn$sapply(strapply(s, "\d+"), ~ sprintf("%s,%s", head(x, 1), tail(x, 1)))
[1] "5,269"  "4,270"  "4,271"  "20,271" "5,213" 

3)这是另一种变体。它给出了一个字符串矩阵:

> strapplyc(s, "(\d+).*\D(\d+)", simplify = rbind)
     [,1] [,2] 
[1,] "5"  "269"
[2,] "4"  "270"
[3,] "4"  "271"
[4,] "20" "271"
[5,] "5"  "213"

4)这是不使用gsubfn的第二个解决方案的变体。 (非 gsubfn 解决方案可以以类似的方式从第一个解决方案派生。

> sapply(strsplit(s,"\D+"),
+          function(x) sprintf("%s,%s", head(Filter(nzchar, x), 1), tail(x, 1)))
[1] "5,269"  "4,270"  "4,271"  "20,271" "5,213" 

前 3 个解决方案使用 gsubfn 包,除第三个解决方案外,其他所有解决方案仅使用简单的正则表达式 "\d+""\D+"

一个稍微通用的解决方案:

sub("^\D*(\d+)-.*-(\d+)\D*$", "\1,\2", v)

相关内容

  • 没有找到相关文章

最新更新