选择R中字符串的一部分

时间:2014-01-02 13:00:05

标签: r grep compare substring

我有一列字符串,如下所示:

 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

3 个答案:

答案 0 :(得分:2)

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 :(得分:2)

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包,除第3个解决方案外,所有解决方案仅使用简单的正则表达式"\\d+""\\D+"

答案 2 :(得分:0)

稍微更通用的解决方案:

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