每 n 个字符分割字符串新列

Posted

技术标签:

【中文标题】每 n 个字符分割字符串新列【英文标题】:Split string every n characters new column 【发布时间】:2019-01-12 13:34:30 【问题描述】:

假设我有一个像这样带有字符串向量 var2 的数据框

var1  var2
1     abcdefghi 
2     abcdefghijklmnop
3     abc 
4     abcdefghijklmnopqrst

将var2每n个字符拆分为新列直到每个字符串结尾的最有效方法是什么,

例如,如果每 4 个字符,输出将如下所示:

var1  var2                  new_var1  new_var2 new_var3  new_var4  new_var5
1     abcdefghi             abcd      efgh     i 
2     abcdefghijklmnop      abcd      efgh     ijkl      mnop 
3     abc                   abc
4     abcdefghijklmnopqrst  abcd      efgh     ijkl      mnop      qrst 

stringr 包?使用“str_split_fixed”

或者使用正则表达式:

gsub("(.4)", "\\1 ", "abcdefghi")

根据 var2 的长度(例如,可以是 10000 个字符)创建进入 new_var_n 的新列的能力。

【问题讨论】:

【参考方案1】:

或者,您可以在 base R 中尝试read.fwf。不需要特殊的包:

tmp <- read.fwf(
    textConnection(dtf$var2),
    widths = rep(4, ceiling(max(nchar(dtf$var2) / 4))),
    stringsAsFactors = FALSE)

cbind(dtf, tmp)

#   var1                 var2   V1   V2   V3   V4   V5
# 1    1            abcdefghi abcd efgh    i <NA> <NA>
# 2    2     abcdefghijklmnop abcd efgh ijkl mnop <NA>
# 3    3                  abc  abc <NA> <NA> <NA> <NA>
# 4    4 abcdefghijklmnopqrst abcd efgh ijkl mnop qrst

【讨论】:

【参考方案2】:

这是一个带有data.table 的选项和一个辅助函数fixed_split,我从this answer 中获取并稍作修改(它使用tstrsplit 而不是strsplit)。

library(data.table)
fixed_split <- function(text, n) 
  data.table::tstrsplit(text, paste0("(?<=.",n,")"), perl=TRUE)

定义n,字符数和new_vars,首先添加的列数

n <- 4
new_vars <- ceiling(max(nchar(df$var2)) / n)

setDT(df)[, paste0("new_var", seq_len(new_vars)) := fixed_split(var2, n = n)][]
#   var1                 var2 new_var1 new_var2 new_var3 new_var4 new_var5
#1:    1            abcdefghi     abcd     efgh        i     <NA>     <NA>
#2:    2     abcdefghijklmnop     abcd     efgh     ijkl     mnop     <NA>
#3:    3                  abc      abc     <NA>     <NA>     <NA>     <NA>
#4:    4 abcdefghijklmnopqrst     abcd     efgh     ijkl     mnop     qrst

【讨论】:

你知道我是否有这样的列表 - [1]“a”“b”“c”“d”,我怎样才能将它们组合成“ab”,“cd” .基本上我使用了 str_split("abcd", "") 并卡住了 @Hardikgupta 您可以考虑使用fixed_split("abcd", 2)(如上定义)而不是str_split【参考方案3】:

这是使用strsplitmatrix 强制的替代方法

str_split_n <- function(x, n = 4) 
    sapply(x, function(ss) 
        nc <- nchar(as.character(ss))
        apply(matrix(replace(
            rep("", n * ceiling(nc / n)), 1:nc, unlist(strsplit(as.character(ss), ""))),
            nrow = n),
            2,
            paste0, collapse = "")
    )


library(dplyr)
library(tidyr)
df %>%
    mutate(tmp = str_split_n(var2)) %>%
    unnest() %>%
    group_by(var1) %>%
    mutate(n = paste0("new_var", 1:n())) %>%
    spread(n, tmp)
## A tibble: 4 x 7
## Groups:   var1 [4]
#   var1 var2                 new_var1 new_var2 new_var3 new_var4 new_var5
#  <int> <fct>                <chr>    <chr>    <chr>    <chr>    <chr>
#1     1 abcdefghi            abcd     efgh     i        NA       NA
#2     2 abcdefghijklmnop     abcd     efgh     ijkl     mnop     NA
#3     3 abc                  abc      NA       NA       NA       NA
#4     4 abcdefghijklmnopqrst abcd     efgh     ijkl     mnop     qrst

【讨论】:

【参考方案4】:

在同一个变量上使用连续的substr

  library(data.table)
  dff <- fread("var1  var2
1     abcdefghi 
2     abcdefghijklmnop
3     abc 
4     abcdefghijklmnopqrst")

  var2 <- dff[["var2"]]
  for (j in 1:5) 
    set(dff, j = paste0("new_var", j), value = substr(var2, 4*j - 3, 4*j))
  
  dff
#>    var1                 var2 new_var1 new_var2 new_var3 new_var4 new_var5
#> 1:    1            abcdefghi     abcd     efgh        i                  
#> 2:    2     abcdefghijklmnop     abcd     efgh     ijkl     mnop         
#> 3:    3                  abc      abc                                    
#> 4:    4 abcdefghijklmnopqrst     abcd     efgh     ijkl     mnop     qrst

由reprex package (v0.2.0) 于 2018 年 8 月 5 日创建。

【讨论】:

【参考方案5】:

您可以使用tidyr::separate

library(tidyr)
n <- ((max(nchar(df$var2)) - 1) %/% 4) + 1
df %>% separate(var2, into=paste0("new_var", seq(n)), sep=seq(n-1)*4, remove = FALSE)
#   var1                 var2 new_var1 new_var2 new_var3 new_var4 new_var5
# 1    1            abcdefghi     abcd     efgh        i                  
# 2    2     abcdefghijklmnop     abcd     efgh     ijkl     mnop         
# 3    3                  abc      abc                                    
# 4    4 abcdefghijklmnopqrst     abcd     efgh     ijkl     mnop     qrst

我们首先使用整数除法计算我们将拥有多少组,然后我们动态定义新名称并使用 sep 参数中的数值在相关位置拆分。

数据

df <- read.table(text="var1  var2
1     abcdefghi 
2     abcdefghijklmnop
3     abc 
4     abcdefghijklmnopqrst",strin=F,h=T)

【讨论】:

以上是关于每 n 个字符分割字符串新列的主要内容,如果未能解决你的问题,请参考以下文章

strtok — 标记分割字符串

strtok — 标记分割字符串

无论c#中的字符是啥,如何根据每三个字符分割一个字符串[重复]

6.14 提取第n个分割的子串

python 每多少位分割字符串

python 每多少位分割字符串