每 n 个字符拆分字符串新列
Split string every n characters new column
假设我有一个像这样的数据框,带有一个字符串向量,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 的长度创建转到 new_var_n 的新列的能力,例如可以是 10000 个字符。
这是一个带有 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
这是使用 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
对同一个变量使用连续的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-08-05。
或者,您可以在 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
您可以使用 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)
假设我有一个像这样的数据框,带有一个字符串向量,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 的长度创建转到 new_var_n 的新列的能力,例如可以是 10000 个字符。
这是一个带有 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
这是使用 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
对同一个变量使用连续的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-08-05。
或者,您可以在 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
您可以使用 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)