每 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】:
这是使用strsplit
和matrix
强制的替代方法
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 个字符分割字符串新列的主要内容,如果未能解决你的问题,请参考以下文章