首页 > 解决方案 > 将列内的字符串拆分为固定长度的子字符串

问题描述

这是我的模拟代码和数据:

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 个组。

非常感激!

标签: rregexdata.table

解决方案


我们可以做到这一点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

推荐阅读