我有一列字符串,看起来像这样:
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)