有没有办法将字母延伸超过26个字符,例如AA,AB,AC ......?

时间:2014-09-16 19:18:55

标签: r

我大部分时间都使用LETTER来表达我的因素,但今天我试图超过26个字符:

LETTERS[1:32]

期待有一个自动递归分解AA,AB,AC ...但是很失望。这仅仅是LETTERS的限制还是有办法使用其他功能获得我正在寻找的东西?

9 个答案:

答案 0 :(得分:33)

702会不够?

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

如果没有,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" ...

答案 1 :(得分:14)

此解决方案使用递归。用法在某种意义上有点不同MORELETTERS不是一个长向量,您必须存储并可能随着输入变大而扩展。相反,它是一个将您的数字转换为新基数的函数。

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"

答案 2 :(得分:12)

excel样式列名的另一种解决方案,通用于任意数量的字母

#' 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
  ))
}

答案 3 :(得分:10)

你可以像这样制作你想要的东西:

LETTERS2<-c(LETTERS[1:26], paste0("A",LETTERS[1:26]))

答案 4 :(得分:7)

又一个选择:

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

调整LETTERSexpand.grid的两个实例,以获得您想要的字母对数。

答案 5 :(得分:7)

eipi10方法的一个变体(正确排序)使用 data.table

library(data.table)
BIG_LETTERS <- c(LETTERS,
                 do.call("paste0",CJ(LETTERS,LETTERS)),
                 do.call("paste0",CJ(LETTERS,LETTERS,LETTERS)))

答案 6 :(得分:5)

生成Excel样式列名的函数,即

# 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)

它可能不是最快的,但它无限延伸并且可以很好地预测。大约需要20秒才能产生100万,BDWGN

(有关详情,请参阅此处:https://stackoverflow.com/a/21689613/903061

答案 7 :(得分:4)

派对有点晚了,但我也想玩。

您也可以使用subsprintf代替paste0,并获得长度为702的向量。

c(LETTERS, sapply(LETTERS, sub, pattern = " ", x = sprintf("%2s", LETTERS)))

答案 8 :(得分:0)

这是列表中的另一个新增内容。这似乎比Gregor(在我的计算机上进行的比较-使用length.out = 1e6他花了12.88秒,我的是6.2)要快一点,并且还可以无限期地扩展。另一方面是它有2个功能,而不仅仅是1个。

make.chars <- function(length.out, case, n.char = NULL) {
  if(is.null(n.char))
    n.char <- ceiling(log(length.out, 26))
  m <- sapply(n.char:1, function(x) {
    rep(rep(1:26, each = 26^(x-1)) , length.out = length.out)
  })
    m.char <- switch(case,
      'lower' = letters[m],
      'upper' = LETTERS[m]
    )
    m.char <- LETTERS[m]
    dim(m.char) <- dim(m)

    apply(m.char, 1, function(x) paste(x, collapse = ""))
}


get.letters <- function(length.out, case = 'upper'){
  max.char <- ceiling(log(length.out, 26))
  grp <- rep(1:max.char, 26^(1:max.char))[1:length.out]
  unlist(lapply(unique(grp), function(n) make.chars(length(grp[grp == n]), case = case, n.char = n)))
}


##
make.chars(5, "lower", 2)
#> [1] "AA" "AB" "AC" "AD" "AE"
make.chars(5, "lower")
#> [1] "A" "B" "C" "D" "E"
make.chars(5, "upper", 4)
#> [1] "AAAA" "AAAB" "AAAC" "AAAD" "AAAE"

tmp <- get.letters(800)
head(tmp)
#> [1] "A" "B" "C" "D" "E" "F"
tail(tmp)
#> [1] "ADO" "ADP" "ADQ" "ADR" "ADS" "ADT"

reprex package(v0.2.1)于2019-03-22创建