lightsnail - 10 months ago 43

R Question

`a`

`a<- matrix(c("A","B","0","1","A","C","D","B","A","C","0","D","B","1","C","D"),4)`

> a

[,1] [,2] [,3] [,4]

[1,] "A" "A" "A" "B"

[2,] "B" "C" "C" "1"

[3,] "0" "D" "0" "C"

[4,] "1" "B" "D" "D"

We find that there are four types of characters in the matrix

`a`

Now we assume that there is a 40% possibility for each character to change into one of the rest of the three characters. For example, "A" has a 40% possibility to change into "B","C" or "D"; "B" has a 40% possibility to change into "A","C" or "D";......

I used the following code with a seed set, the answer is right.

`set.seed(2016)`

pob <- 0.4

a[a=="A"] <- ifelse(runif(sum(a=="A")) <= pob, sample(c(1:4)[-1],sum(a=="A"),replace = T), 1)

a[a=="B"] <- ifelse(runif(sum(a=="B")) <= pob, sample(c(1:4)[-2],sum(a=="B"),replace = T), 2)

a[a=="C"] <- ifelse(runif(sum(a=="C")) <= pob, sample(c(1:4)[-3],sum(a=="C"),replace = T), 3)

a[a=="D"] <- ifelse(runif(sum(a=="D")) <= pob, sample(c(1:4)[-4],sum(a=="D"),replace = T), 4)

a[a==1] <- "A"

a[a==2] <- "B"

a[a==3] <- "C"

a[a==4] <- "D"

> a

[,1] [,2] [,3] [,4]

[1,] "B" "A" "B" "C"

[2,] "D" "C" "A" "A"

[3,] "0" "B" "0" "C"

[4,] "C" "A" "D" "D"

But I wonder whether there is a much easier way to work this problem out, thanks in advance.

`Modified`

As there is "0" and "1" which are not characters in the matrix

`a`

`set.seed(2016)`

pob <- 0.4

a[a=="A"] <- ifelse(runif(sum(a=="A")) <= pob, sample(c(1:4)[-1],sum(a=="A"),replace = T), "one")

a[a=="B"] <- ifelse(runif(sum(a=="B")) <= pob, sample(c(1:4)[-2],sum(a=="B"),replace = T), "two")

a[a=="C"] <- ifelse(runif(sum(a=="C")) <= pob, sample(c(1:4)[-3],sum(a=="C"),replace = T), "three")

a[a=="D"] <- ifelse(runif(sum(a=="D")) <= pob, sample(c(1:4)[-4],sum(a=="D"),replace = T), "four")

a[a=="one"] <- "A"

a[a=="two"] <- "B"

a[a=="three"] <- "C"

a[a=="four"] <- "D"

> a

[,1] [,2] [,3] [,4]

[1,] "2" "3" "A" "1"

[2,] "B" "2" "C" "1"

[3,] "0" "D" "0" "1"

[4,] "1" "B" "2" "2"

Answer Source

if I understand correctly, the following code does what you want, except the singular 0 and 1s.

```
a <- matrix(c("A","B","0","1","A","C","D","B","A","C","0","D","B","1","C","D"),4)
# states that are subjected to mutation
s <- c('A', 'B', 'C', 'D')
# matrix of transition prob
b <- matrix(1, nrow = 4, ncol = 4, dimnames = list(s, NULL))
diag(b) <- 0
# mutation prob
prob <- 0.4
# sites that can be changed
indx <- a %in% s
a[indx] <- ifelse(
runif(sum(indx)) > prob,
a[indx],
sapply(a[indx], function(i) sample(s, 1, prob = b[i, ]))
)
```