is there a way to extend LETTERS past 26 characters e.g., AA, AB, AC…?

前端 未结 9 1687
情书的邮戳
情书的邮戳 2020-12-03 00:52

I use LETTERS most of the time for my factors but today I tried to go beyond 26 characters:

LETTERS[1:32]

Expecting there to be an automati

相关标签:
9条回答
  • 2020-12-03 01:30

    Another solution for excel style column names, generalized to any number of letters

    #' Excel Style Column Names
    #'
    #' @param n maximum number of letters in column name
    excel_style_colnames <- function(n){
      unlist(Reduce(
        function(x, y) as.vector(outer(x, y, 'paste0')),
        lapply(1:n, function(x) LETTERS),
        accumulate = TRUE
      ))
    }
    
    0 讨论(0)
  • 2020-12-03 01:31

    A variant on eipi10's method (ordered correctly) using data.table:

    library(data.table)
    BIG_LETTERS <- c(LETTERS,
                     do.call("paste0",CJ(LETTERS,LETTERS)),
                     do.call("paste0",CJ(LETTERS,LETTERS,LETTERS)))
    
    0 讨论(0)
  • 2020-12-03 01:33

    This solution uses recursion. Usage is a bit different in the sense MORELETTERS is not a long vector you will have to store and possibly expand as your inputs get larger. Instead, it is a function that converts your numbers into the new base.

    extend <- function(alphabet) function(i) {
       base10toA <- function(n, A) {
          stopifnot(n >= 0L)
          N <- length(A)
          j <- n %/% N 
          if (j == 0L) A[n + 1L] else paste0(Recall(j - 1L, A), A[n %% N + 1L])
       }   
       vapply(i-1L, base10toA, character(1L), alphabet)
    }
    MORELETTERS <- extend(LETTERS)         
    
    MORELETTERS(1:1000)
    # [1] "A" "B" ... "ALL"
    MORELETTERS(c(1, 26, 27, 1000, 1e6, .Machine$integer.max))
    # [1] "A"       "Z"       "AA"      "ALL"     "BDWGN"   "FXSHRXW"
    
    0 讨论(0)
  • 2020-12-03 01:36

    Yet another option:

    l2 = c(LETTERS, sort(do.call("paste0", expand.grid(LETTERS, LETTERS[1:3]))))
    

    Adjust the two instances of LETTERS inside expand.grid to get the number of letter pairs you'd like.

    0 讨论(0)
  • 2020-12-03 01:39

    A function to produce Excel-style column names, i.e.

    # A, B, ..., Z, AA, AB, ..., AZ, BA, BB, ..., ..., ZZ, AAA, ...
    
    letterwrap <- function(n, depth = 1) {
        args <- lapply(1:depth, FUN = function(x) return(LETTERS))
        x <- do.call(expand.grid, args = list(args, stringsAsFactors = F))
        x <- x[, rev(names(x)), drop = F]
        x <- do.call(paste0, x)
        if (n <= length(x)) return(x[1:n])
        return(c(x, letterwrap(n - length(x), depth = depth + 1)))
    }
    
    letterwrap(26^2 + 52) # through AAZ
    
    ## This will take a few seconds:
    # x <- letterwrap(1e6)
    

    It's probably not the fastest, but it extends indefinitely and is nicely predictable. Took about 20 seconds to produce through 1 million, BDWGN.

    (For a few more details, see here: https://stackoverflow.com/a/21689613/903061)

    0 讨论(0)
  • 2020-12-03 01:51

    Would 702 be enough?

    LETTERS702 <- c(LETTERS, sapply(LETTERS, function(x) paste0(x, LETTERS)))
    

    If not, how about 18,278?

    MOAR_LETTERS <- function(n=2) {
      n <- as.integer(n[1L])
      if(!is.finite(n) || n < 2)
        stop("'n' must be a length-1 integer >= 2")
    
      res <- vector("list", n)
      res[[1]] <- LETTERS
      for(i in 2:n)
        res[[i]] <- c(sapply(res[[i-1L]], function(y) paste0(y, LETTERS)))
    
      unlist(res)
    }
    ml <- MOAR_LETTERS(3)
    str(ml)
    # chr [1:18278] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" ...
    
    0 讨论(0)
提交回复
热议问题