这是我的模拟代码和数据:
library(data.table)
library(stringr)
data <- data.table(string = c("aaaaaaaaa", "bbbbbb", "ccccccccccccccc", "aaa"))
data[, length := nchar(string)]
data
string length
1: aaaaaaaaa 9
2: bbbbbb 6
3: ccccccccccccccc 15
4: aaa 3
我需要将“字符串”列拆分为长度为3的子字符串。我希望结果在单独的列中,并且子字符串分开。我试图将for
循环与seq
结合使用,但是这太慢了,因为我的实际数据超过700万行。
这是我的for循环,在新列中具有所需结果。
for(i in 1:nrow(data)){
data[i , split := paste(str_sub(string, seq(from = 1, to = length, by = 3),
seq(from = 3, to = length, by = 3)), collapse = " - ")]
}
哪一个给我我想要的结果-多么缓慢。
> data
string length split
1: aaaaaaaaa 9 aaa - aaa - aaa
2: bbbbbb 6 bbb - bbb
3: ccccccccccccccc 15 ccc - ccc - ccc - ccc - ccc
4: aaa 3 aaa
我正在寻找不使用for
循环的解决方案,因此我猜测它必须基于regex
。
请注意,列string
的长度可能有所不同,但始终为3的倍数,并且必须始终分为3组。
非常感谢!
答案 0 :(得分:2)
我们可以使用gsub
data[, split := trimws(gsub("(...)", "\\1 - ", string), whitespace = '[- ]')][]
# string length split
#1: aaaaaaaaa 9 aaa - aaa - aaa
#2: bbbbbb 6 bbb - bbb
#3: ccccccccccccccc 15 ccc - ccc - ccc - ccc - ccc
#4: aaa 3 aaa
答案 1 :(得分:1)
您可以尝试一下。 (?<=^(...)*)(?!^|$)
。但是我不知道r语言是否支持它。
答案 2 :(得分:1)
我们可以使用strsplit
将字符串每3个字符分割一次,然后paste
分成一个字符串。
library(data.table)
data[, split := lapply(strsplit(string, "(?<=.{3})", perl=TRUE),
paste, collapse = " - ")]
data
# string split
#1: aaaaaaaaa aaa - aaa - aaa
#2: bbbbbb bbb - bbb
#3: ccccccccccccccc ccc - ccc - ccc - ccc - ccc
#4: aaa aaa