Andrew
Andrew

Reputation: 13

changing values in a matrix using an if function

I have a matrix comprised of elements and their ratings e.g.

matrix(data=c("A","B","C",NA,0.7,0.5,0,NA,"D","E","F","G",0.9,0.4,0.2,0.005),nrow=4,byrow=FALSE)

    [,1] [,2]  [,3] [,4]   
[1,] "A"  "0.7" "D"  "0.9"  
[2,] "B"  "0.5" "E"  "0.4"  
[3,] "C"  "0"   "F"  "0.2"  
[4,] NA   NA    "G"  "0.005"

I would like to replace all the ratings (and the elements next to them) which are less than 0.1 with NA.

e.g.

matrix(data=c("A","B",NA,NA,0.7,0.5,NA,NA,"D","E","F",NA,0.9,0.4,0.2,NA),nrow=4, byrow=FALSE)

    [,1] [,2]  [,3] [,4]  
[1,] "A"  "0.7" "D"  "0.9"  
[2,] "B"  "0.5" "E"  "0.4"  
[3,] NA   NA    "F"  "0.2"  
[4,] NA   NA    NA   NA    

I was about to do this in a large for loop when I thought there must be a better way. Any suggestions will be much appreciated.

Upvotes: 1

Views: 203

Answers (2)

agstudy
agstudy

Reputation: 121568

I am agrre with others. It is preferable to use matrix for numeric, and data.frame for different tpes columns.

You don't precise what do you means by the elements next to the element < 0.1, but in understand from your comments character in the adjacent (left).

Here my solution. I transform your matrix to a vector for simple indexing, than I transform it again to a matrix.

mat <- matrix(data=c("A","B","C", NA,
                     0.7,0.5,0,NA,
                     "D","E","F","G",
                     0.9,0.4,0.2,0.005),
                     nrow=4,byrow=FALSE)
dim(mat) <- NULL
mat[c(which(mat<0.1)-4,which(mat<0.1))] <- NA
matrix(mat,nrow=4,byrow=F)

   [,1] [,2]  [,3] [,4] 
[1,] "A"  "0.7" "D"  "0.9"
[2,] "B"  "0.5" "E"  "0.4"
[3,] NA   NA    "F"  "0.2"
[4,] NA   NA    NA   NA  

Upvotes: 0

Ina
Ina

Reputation: 4470

In your example 'C' goes to NA. I presume this is a mistake so I've not replicated it.

mat <- matrix(data=c("A","B","C",NA,0.7,0.5,0,NA,"D","E","F","G",0.9,0.4,0.2,0.005),nrow=4,byrow=FALSE)
mat[mat < 0.1] <- NA

Furthermore, if you are truly storing elements and their ratings, perhaps a data.frame would be a better choice:

> data.frame(element=toupper(letters[1:7]), rating=c(0.7,0.5,0,0.9,0.4,0.2,0.005))
   element  rating
1        A   0.700
2        B   0.500
3        C   0.000
4        D   0.900
5        E   0.400
6        F   0.200
7        G   0.005

You could then make these values, and their entire row, NA with:

> df[df[,"rating"] < 0.1,] <- NA
> df
  element rating
1       A    0.7
2       B    0.5
3    <NA>     NA
4       D    0.9
5       E    0.4
6       F    0.2
7    <NA>     NA

Finally, here's how to transform your matrix to a data.frame

elements <- as.vector(mat[,seq(from=1, to=ncol(mat),by=2)])
ratings <- as.vector(mat[,seq(from=2, to=ncol(mat),by=2)])
df <- data.frame(element=elements,rating=ratings)

Upvotes: 1

Related Questions