Есть ли способ расширить ПИСЬМА прошлых 26 символов, например, AA, AB, AC...?
Я использую LETTERS большую часть времени для моих факторов, но сегодня я пытался выйти за пределы 26 символов:
LETTERS[1:32]
Ожидая, что будет автоматическая рекурсивная факторизация AA, AB, AC... Но была разочарована. Это просто ограничение ПИСЬМА или есть способ получить то, что я ищу, используя другую функцию?
Ответы
Ответ 1
Достаточно ли 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" ...
Ответ 2
В этом решении используется рекурсия. Использование немного отличается в смысле 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"
Ответ 3
Другое решение для имен столбцов типа 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
))
}
Ответ 4
Вы можете сделать так, как хотите:
LETTERS2<-c(LETTERS[1:26], paste0("A",LETTERS[1:26]))
Ответ 5
Еще один вариант:
l2 = c(LETTERS, sort(do.call("paste0", expand.grid(LETTERS, LETTERS[1:3]))))
Откорректируйте два экземпляра LETTERS
внутри expand.grid
, чтобы получить количество пар букв, которое вы хотели бы.
Ответ 6
Вариант по методу eipi10 (упорядоченный правильно) с использованием data.table:
library(data.table)
BIG_LETTERS <- c(LETTERS,
do.call("paste0",CJ(LETTERS,LETTERS)),
do.call("paste0",CJ(LETTERS,LETTERS,LETTERS)))
Ответ 7
Функция для создания имен столбцов в стиле 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 секунд, чтобы произвести через 1 миллион, BDWGN
.
(Более подробно см. здесь: fooobar.com/questions/210936/...)
Ответ 8
Немного поздно на вечеринку, но я тоже хочу играть.
Вы также можете использовать sub
и sprintf
вместо paste0
и получить вектор длины 702.
c(LETTERS, sapply(LETTERS, sub, pattern = " ", x = sprintf("%2s", LETTERS)))