Jeff Jeff - 3 months ago 6
R Question

R - Replacing values in a matrix row conditional on the values in one of the columns

Using R I have data in a matrix with three columns, and I would like to replace the value in the first two columns conditional on the value in the third. If the third column is '1', I want to replace the values in the first and second columns both with 0.5 (the third column is irrelevant, I will be dropping it later), otherwise, I want to leave them as they are.

> MAT
a b c
t4 0 1 0
t5 1 0 0
t6 0 1 0
t7 0 1 0
t8 0 1 0
t3 0 1 0
t1 1 0 0
t2 0 1 0
t9 0 0 1
t10 0 0 1


I can do this manually:

> MAT["t9",1:3]=c(.5,.5,0)
> MAT["t10",1:3]=c(.5,.5,0)
> MAT
a b c
t4 0.0 1.0 0
t5 1.0 0.0 0
t6 0.0 1.0 0
t7 0.0 1.0 0
t8 0.0 1.0 0
t3 0.0 1.0 0
t1 1.0 0.0 0
t2 0.0 1.0 0
t9 0.5 0.5 0
t10 0.5 0.5 0


but I have about 20 sets of data and for some of them I will have to replace about 100 rows. I was wondering whether there is code I can use to automate it. I've been trying ifelse() but I don't understand the results:

>ifelse(MAT[,3]==1,MAT[,1:3]==c(0.5,0.5,0),MAT[,3]==0)
t4 t5 t6 t7 t8 t3 t1 t2 t9 t10
TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
> ifelse(MAT[,3]==1,MAT[,1:3]==c(0.5,0.5,0),ifelse(MAT[,2]==1,MAT[,2]==1,MAT[,1]==1))
t4 t5 t6 t7 t8 t3 t1 t2 t9 t10
TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE
> ifelse(MAT[,3]==1,c(0.5,0.5,0),MAT)
t4 t5 t6 t7 t8 t3 t1 t2 t9 t10
0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.5 0.5
> ifelse(MAT[,1:3]==c(0,0,1),MAT[,1:3]==c(0.5,0.5,0),MAT)
a b c
t4 0.0 1.0 0
t5 1.0 0.0 0
t6 0.0 1.0 0
t7 0.0 1.0 0
t8 0.0 0.0 0
t3 0.0 1.0 0
t1 1.0 0.0 0
t2 0.0 0.0 0
t9 0.5 0.5 0
t10 0.5 0.5 0


I thought the first would would work by checking for whether the 3rd column = 1, and if so replacing the row with 0.5, 0.5, 0.0, and if not leaving it at 0. I thought the second was clunkier but might accomplish the same thing. The last successfully made the changes, but also eliminated other data that I wanted to keep. I'm guessing at this point that ifelse is not the way to go about this, but I'm not sure how else to do it.

Thanks in advance.

Vic Vic
Answer

Are you happy with the following?

a<-c(0,1,0,0,0,0,1,0,0,0)
b<-c(1,0,1,1,1,1,0,1,0,0)
c<-c(0,0,0,0,0,0,0,0,1,1)

MAT<-data.frame(a,b,c)
colnames(data)<-c("a","b","c")

MAT$a[data$c == 1] <- 0.5
MAT$b[data$c == 1] <- 0.5
MAT<-data[,1:2]

Or you can even do:

a<-c(0,1,0,0,0,0,1,0,0,0)
b<-c(1,0,1,1,1,1,0,1,0,0)
c<-c(0,0,0,0,0,0,0,0,1,1)

MAT<-cbind(a,b,c)

for(i in 1:2){
MAT[,i][MAT[,3] == 1] <- 0.5
}
MAT<-MAT[,1:2]

Notice: 3 column is only used for the logical test, its values are unchanged.

Comments