Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert excel column names to numbers

Tags:

function

r

I wanted to write a function to convert excel column-names into the corresponding number. What I have come up with so far, works only partially. That is, inputs where the lower letter comes first ("AB", AC", etc.) work fine. But it does not work the other way around ("BA", "CA", etc.). I have traced the error to the line y <- which(base::LETTERS==x) but I do not really understand how these boolean operators work on vectors. Any advice?

#so to pass excel column-names directly, this function should do the trick
LettersToNumbers <- function(input){
    x <- toupper(substring(input, c(1:nchar(input)), c(1:nchar(input)))) #parse input-string
    y <- which(base::LETTERS==x) #letters to numbers
    y <- rev(y) #reverse
    #base26 conversion:
    result <- 0
    for (i in 1:length(y)){
        result <- result + ( y[i]*26^(i-1) )
    }
    return(result)
}

Actually it turns out there are some more examples that are not working. Here are some, and I do not really understand what is going on.

> which(LETTERS==c("A", "B"))
[1] 1 2
> which(LETTERS==c("A", "C"))
[1] 1
> which(LETTERS==c("A", "D"))
[1] 1 4
> which(LETTERS==c("D", "A"))
integer(0)
> 
like image 799
vanao veneri Avatar asked Sep 06 '25 03:09

vanao veneri


1 Answers

This is quick and dirty, but I think it gets you what you want. It should work for an arbitrary string length.

# Input: A string of letters s
# Output: Corresponding column number
LettersToNumbers <- function(s){
  # Uppercase
  s_upper <- toupper(s)
  # Convert string to a vector of single letters
  s_split <- unlist(strsplit(s_upper, split=""))
  # Convert each letter to the corresponding number
  s_number <- sapply(s_split, function(x) {which(LETTERS == x)})
  # Derive the numeric value associated with each letter
  numbers <- 26^((length(s_number)-1):0)
  # Calculate the column number
  column_number <- sum(s_number * numbers)
  column_number
}
# Vectorize in case you want to pass more than one column name in a single call
LettersToNumbers <- Vectorize(LettersToNumbers)

# Quick tests
LettersToNumbers("A")
LettersToNumbers("Z")
LettersToNumbers("AA")
LettersToNumbers("BA")
LettersToNumbers("AAA")
LettersToNumbers(LETTERS)

As noted in a comment above, the primary issue with your code is vector recycling, which this function avoids by using sapply.

like image 118
Derek Damron Avatar answered Sep 08 '25 20:09

Derek Damron