pat_krat
pat_krat

Reputation: 179

Simple loop for changing file names doesn't work

I wrote the following loop to convert user input, which can be single-, two- or three digit numbers, into all three digit numbers; such that an input vector [7, 8, 9, 10, 11] would be converted into an output vector [007, 008, 009, 010, 011]. This is my code:

zeroes <- function(id){

    for(i in 1:length(id)){
        if(id[i] <= 9){
            id[i] <- paste("00", id[i], sep = "")
        }
        else if(id[i] >= 10 && id[i] <= 99){
            id[i] <- paste("0", id[i], sep = "")
        }
    }
id
}

For an input vector

id <- 50:100

I get the following output:

 [1] "050"   "0051"  "0052"  "0053"  "0054"  "0055"  "0056"  "0057"  "0058"  "0059" 
[11] "0060"  "0061"  "0062"  "0063"  "0064"  "0065"  "0066"  "0067"  "0068"  "0069" 
[21] "0070"  "0071"  "0072"  "0073"  "0074"  "0075"  "0076"  "0077"  "0078"  "0079" 
[31] "0080"  "0081"  "0082"  "0083"  "0084"  "0085"  "0086"  "0087"  "0088"  "0089" 
[41] "090"   "091"   "092"   "093"   "094"   "095"   "096"   "097"   "098"   "099"  
[51] "00100"

So, it looks like for id[1] the function works, then there is a bug for the following numbers, but for id[41:50], I get the correct output again. I haven't been able to figure out why this is the case, and what I am doing wrong. Any suggestions are warmly welcomed.

Upvotes: 1

Views: 53

Answers (1)

Spacedman
Spacedman

Reputation: 94267

Its because when you do the first replacement on id in your function, the vector becomes character (because a vector can't store numbers and characters).

So zeroes(51) works fine:

> zeroes(51)
[1] "051"

but if its the second item, it fails:

> zeroes(c(50,51))
[1] "050"  "0051"

because by the time your loop gets on to the 51, its actually "51" in quotes. And that fails:

> zeroes("51")
[1] "0051"

because "51" is less than 9:

> "51"<9
[1] TRUE

because R converts the 9 to a "9" and then does a character comparison, so only the "5" gets compared with the "9" and "5" is before "9" in the collating sequence alphabet.

Other languages might convert the character "51" to numeric and then compare with the numeric 9 and say "51"<9 is False, but R does it this way.

Lesson: don't overwrite your input vectors! (and use sprintf).

Upvotes: 6

Related Questions