将字符串向量中的元素与定义的元素大小组合在一起,并考虑非事件大小

Combining elements in a string vector with defined element size and accounting for not event sizes

给出的是向量:

vec <- c(LETTERS[1:10])

我希望能够按以下方式组合它:

resA <- c("AB", "CD", "EF", "GH", "IJ")
resB <- c("ABCDEF","GHIJ")

其中向量 vec 的元素根据构成结果向量的新元素的所需大小合并在一起。在 resA 的情况下是 2,在 resB 的情况下是 5

所需的解决方案特征


尝试次数

一开始,我想的是在线上使用一些东西:

c(
  paste0(vec[1:2], collapse = ""),
  paste0(vec[3:4], collapse = ""),
  paste0(vec[5:6], collapse = "")
  # ...
)

但这必须进行调整以跳过 vec 的其余 pairs/bigger 组并处理通常较小的最后一组。

vec <- c(LETTERS[1:10])

f1 <- function(x, n){
  f <- function(x) paste0(x, collapse = '')
  regmatches(f(x), gregexpr(f(rep('.', n)), f(x)))[[1]]
}

f1(vec, 2)
# [1] "AB" "CD" "EF" "GH" "IJ"

f2 <- function(x, n)
  apply(matrix(x, nrow = n), 2, paste0, collapse = '')

f2(vec, 5)
# [1] "ABCDE" "FGHIJ"

f3 <- function(x, n) {
  f <- function(x) paste0(x, collapse = '')
  strsplit(gsub(sprintf('(%s)', f(rep('.', n))), '\1 ', f(x)), '\s+')[[1]]
}

f3(vec, 4)
# [1] "ABCD" "EFGH" "IJ"  

我想说最后一个是最好的,因为 n 对于其他人来说必须是一个因素,否则你会收到警告或回收

编辑 - 更多

f4 <- function(x, n) {
  f <- function(x) paste0(x, collapse = '')
  Vectorize(substring, USE.NAMES = FALSE)(f(x), which((seq_along(x) %% n) == 1),
                                          which((seq_along(x) %% n) == 0))
}

f4(vec, 2)
# [1] "AB" "CD" "EF" "GH" "IJ"

f5  <- function(x, n)
  mapply(function(x) paste0(x, collapse = ''),
         split(x, c(0, head(cumsum(rep_len(sequence(n), length(x)) %in% n), -1))),
         USE.NAMES = FALSE)

f5(vec, 4)
# [1] "ABCD" "EFGH" "IJ"  

这是我想出的。使用 Harlan 在 this question 中的想法,您可以将向量拆分为不同数量的块。您还想在这里 lapply() 中使用您的 paste0() 想法。最后,您取消列出一个列表。

unlist(lapply(split(vec, ceiling(seq_along(vec)/2)), function(x){paste0(x, collapse = "")}))

#   1    2    3    4    5 
#"AB" "CD" "EF" "GH" "IJ" 

unlist(lapply(split(vec, ceiling(seq_along(vec)/5)), function(x){paste0(x, collapse = "")}))

#      1       2 
#"ABCDE" "FGHIJ" 

unlist(lapply(split(vec, ceiling(seq_along(vec)/3)), function(x){paste0(x, collapse = "")}))

#    1     2     3     4 
#"ABC" "DEF" "GHI"   "J" 

这是另一种方法,使用原始数组。 旁注,使用单词并不简单,因为至少有两种方法可以理解它:您可以单独保留每个单词,或者先折叠它们以获得单独的字符。下一个函数可以处理这两个选项。

vec <- c(LETTERS[1:10])
vec2 <- c("AB","CDE","F","GHIJ")

cuts <- function(x, n, bychar=F) {
    if (bychar) x <- unlist(strsplit(paste0(x, collapse=""), ""))
    ii <- seq_along(x)
    li <- split(ii, ceiling(ii/n))
    return(sapply(li, function(y) paste0(x[y], collapse="")))
}

cuts(vec2,2,F)
#      1       2 
# "ABCDE" "FGHIJ" 

cuts(vec2,2,T)
#    1    2    3    4    5 
# "AB" "CD" "EF" "GH" "IJ"