【问题标题】:Combining elements in a string vector with defined element size and accounting for not event sizes将字符串向量中的元素与定义的元素大小相结合并考虑非事件大小
【发布时间】:2016-01-24 03:12:37
【问题描述】:

给定是向量:

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

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

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

向量vec 的元素根据构成结果向量的新元素的所需大小合并在一起。对于resA,这是2,对于resB,这是5

所需的解决方案特征

  • 该解决方案应允许在元素大小方面具有灵活性,即我可能希望向量的元素大小为 2 或 20
  • 向量中可能没有足够的元素来匹配所需的块大小,在这种情况下,最后一个元素应该相应地缩短(如图所示)
  • 这不应该有所作为,但解决方案也应该适用于单词

尝试

最初,我正在考虑使用在线的东西:

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

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

【问题讨论】:

  • 您可能会发现this question 很有帮助。
  • @jazzurro 我去看看,我需要的是那个,但似乎是另一轮。

标签: r string vector paste


【解决方案1】:

这是我想出的。使用 this question 中的 Harlan 的想法,您可以将向量拆分为不同数量的块。您还想在此处的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" 

【讨论】:

    【解决方案2】:
    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"  
    

    【讨论】:

      【解决方案3】:

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

      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" 
      

      【讨论】:

        猜你喜欢
        • 2020-04-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-10
        • 2012-02-12
        相关资源
        最近更新 更多