The problem has to do with the fact that you're replacing numbers with characters. Vectors can only have elements of one class, so when you replace some of the elements with "A" in your first step, all of the columns with those elements are coerced to character vectors. Check it out:
> set.seed(100)
> Mydata=sample(-5:5,size = 50,replace = T)
> Mydata=as.data.frame(matrix(Mydata,nrow = 10))
> str(Mydata)
'data.frame': 10 obs. of 5 variables:
$ V1: int -2 -3 1 -5 0 0 3 -1 1 -4
$ V2: int 1 4 -2 -1 3 2 -3 -2 -2 2
$ V3: int 0 2 0 3 -1 -4 3 4 1 -2
$ V4: int 0 5 -2 5 2 4 -4 1 5 -4
$ V5: int -2 4 3 4 1 0 3 4 -3 -2
> Mydata[Mydata<=-1 & Mydata>-1.5] = "A"
> str(Mydata)
'data.frame': 10 obs. of 5 variables:
$ V1: chr "-2" "-3" "1" "-5" ...
$ V2: chr "1" "4" "-2" "A" ...
$ V3: chr "0" "2" "0" "3" ...
$ V4: int 0 5 -2 5 2 4 -4 1 5 -4
$ V5: int -2 4 3 4 1 0 3 4 -3 -2
Interestingly enough, it turns out R will allow you to use characters in tests of (in)equality. So when you apply the subsequent rules, it will continue to replace character values that satisfy the inequality rather than throwing a warning or error. For example:
> char_vec <- c("A", 1, 2, -1)
> char_vec
[1] "A" "1" "2" "-1"
> char_vec > 0
[1] TRUE TRUE TRUE FALSE
It turns out all upper case letters (and all lower case letters, for that matter) are greater than -1, so the whole matrix ends up getting replaced by D's in the last step.
> toupper(letters) > -1
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[19] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
The easiest way to prevent this behavior is by using ifelse
, as pointed out by Aaghaz. Another option would be to create a new matrix rather than progressively overwriting the original:
> Newdata <- Mydata
> Newdata[Mydata<=-1 & Mydata>-1.5] = "A"
> Newdata[Mydata<=-1.5 & Mydata>-2] = "B"
> Newdata[Mydata<=-2] = "C"
> Newdata[Mydata>-1] = "D"