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)
>
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With