我必须用分隔符“-"分割一个字符串,并去掉最右边的部分。
SKU <- c("PPM-UA-L", "RVK-JI-XL", "KMN-WO-XS", "YYL-S")
然而,在下面的代码中,[,3]并不适用于所有情况,因为其中一些代码只有一个“-"。在下面的示例中,最后一个值“YYL-S”将不返回任何内容。
size <- str_split(SKU, "-", simplify = T)[ ,3]
我也试过用这个来做后向索引,但是得到了错误信息。也试过[,-1],但是R中的负索引号不表示后向计数。
size <- str_split(SKU, "-", simplify = T)(rev[ ,3])
3条答案
按热度按时间t1qtbnec1#
矢量化字符串操作比在内存中创建和销毁对象更快(参见下面的基准测试)
创建不需要的向量列表的解决方案往往相对较慢,您可以在这里使用正则表达式替换所有内容,包括最后的
-
。插入符号(
^
)是匹配字符串开头的正则表达式metacharacter。匹配除新行之外的任何字符。+
表示“匹配前面的字符一次或多次”。.+
组合是greedy,表示它将查找从字符串开头到结尾的最长匹配。总而言之,这意味着,从字符串的开头开始匹配,直到并包括最后的-
。sub()
函数将x
中第一个出现的pattern
(在本例中为SKU
)替换为replacement
(在本例中为空字符串)。您可以在这里阅读更多关于正则表达式中使用的语法。
基准测试
我以五种方法为基准:
1.底座R
sub()
。1.碱基R
strsplit() |> sapply()
。1.基础R
strsplit() |> vapply()
。stringr::str_split_i()
.stringr::str_split() |> vapply(\(x) tail(x, 1), character(1))
.1.基本R后视:
regmatches(gregexpr()
.stringr::str_extract()
后视。我将向量从
10
重复到1e5
多次。sub()
始终是最快的方法,具有最少的垃圾收集(gc
),即最少的内存分配。base::strsplit()
和stringr::str_split()
之间没有太大的区别。sapply
看起来与vapply()
没有区别。stringr::str_split_i()
比其他分割向量的方法更快,并且具有更少的垃圾收集,但不如sub()
快。带lookbehind的
stringr::str_extract()
几乎和sub()
一样快,而在带regmatches(gregexpr())
的base R中使用相同的模式要慢得多(可能是因为它返回一个列表)。生成绘图的代码
gmol16392#
您可以将
str_split_i
与i = -1
一起使用来获取最后一部分:xvw2m8pv3#
为什么不将
str_extract
与lookbehind(?<=-)
一起使用呢?lookbehind(?<=-)
是一个否定字符类,不允许使用-
字符,最后是最后一个位置锚$
: