R语言 替换/查找字符串中的令牌的有效方法

ddrv8njm  于 2023-07-31  发布在  其他
关注(0)|答案(1)|浏览(80)

我有一个大向量x~200k个元素),其中每个元素都是逗号分隔的字符串。我还有一个小的查找表lkp,它将旧字符串Map到新字符串。为了这个例子,让我们假设这只是一个命名向量。
我想做的是:
1.我想将x中的每个元素拆分为它的标记
1.在lkp的帮助下替换令牌
1.从替换中删除重复项并排序
一个相当直接的实现看起来像这样:

library(stringr)
x <- c("a,b,c", "c", "b,c", "a,b")
lkp <- c(a = "A", b = "A", c = "B")

tokens <- str_split(x, fixed(","))
lapply(tokens, \(t) sort(unique(lkp[t])))

# [[1]]
# [1] "A" "B"

# [[2]]
# [1] "B"

# [[3]]
# [1] "A" "B"

# [[4]]
# [1] "A"

字符集
我观察到,虽然str_split非常快,但lapply可能需要相当长的时间:

library(tictoc)
xbig <- x[sample(length(x), 2e6, TRUE)]
tic("str_split")
tokens <- str_split(xbig, fixed(","))
toc()
# str_split: 0.89 sec elapsed

tic("lapply")
res <- lapply(tokens, \(t) sort(unique(lkp[t])))
toc()
# lapply: 60.33 sec elapsed


所以我想知道,是否有更聪明的方法来利用矢量化?
如果去掉唯一性和排序属性,更好的方法是

tic("split")
res <- split(lkp[unlist(tokens)], rep(seq_along(tokens), lengths(tokens)))
toc()
# split: 2.89 sec elapsed


所以我想知道(考虑到str_split的超快速度)是否有一个regex解决方案可以从stringr的速度中受益?

ghhkc1vu

ghhkc1vu1#

我们可以用

  1. str_replace_all利用命名向量lkp进行就地替换。
    1.使用str_split在逗号上分割数据。
    1.获取唯一值。
library(stringr)
library(tictoc)

lapply(str_split(str_replace_all(x, lkp), fixed(",")), unique)

#[[1]]
#[1] "A" "B"

#[[2]]
#[1] "B"

#[[3]]
#[1] "A" "B"

#[[4]]
#[1] "A"

字符集
在更大的向量上。

tic("str_replace_all")
step1 <- str_replace_all(xbig, lkp)
toc()

#str_replace_all: 1.288 sec elapsed

tic("str_split")
step2 <- str_split(step1, fixed(","))
toc()

#str_split: 1.328 sec elapsed

tic("unique")
step3 <- lapply(step2, unique)
toc()
#unique: 5.955 sec elapsed


这个时间比你现在的时间要好,但是我认为第2步和第3步可以一步解决,而不需要使用正则表达式来分割字符串,但是现在还不能找到合适的正则表达式。

相关问题