Reputation: 117
I have a matrix called M, where each row only has two possible letters:
M <- structure(list(id1 = c("AA", "AB", "AA", "AC"), id2 = c("AA",
"AB", "AA", "CC"), id3 = c("AA", "AA", "AB", "AC"), id4 = c("AA",
"AB", "AB", "AA"), id5 = c("AA", "BB", "AA", "CC"), id6 = c("AA",
"AB", "BB", "CC"), id7 = c("AA", "AB", "BB", "CC"), id8 = c("AA",
"AB", "BB", "AC"), id9 = c("AA", "AB", "AB", "AA")), .Names = c("id1",
"id2", "id3", "id4", "id5", "id6", "id7", "id8", "id9"), class = "data.frame", row.names = c(NA,
-4L))
M
# id1 id2 id3 id4 id5 id6 id7 id8 id9
# 1 AA AA AA AA AA AA AA AA AA
# 2 AB AB AA AB BB AB AB AB AB
# 3 AA AA AB AB AA BB BB BB AB
# 4 AC CC AC AA CC CC CC AC AA
I need to replace the letters so that, for each row, the first one is assigned 0 and the second 1.
So for row 2, A=0, B=1, for row 5 A=0, C=1.
I've been told to do it with the below for
loop, but it doesn't seem to work, I only get results for one row back. Can anyone tell me what I'm doing wrong?
This is my code:
for (i in 1:500)
{
results= M[i,]
hold=unique(unlist(strsplit(unique(results),"")))
hold=hold[is.na(hold)==F]
sort(hold)
results=gsub(hold[1],"0",results)
results=gsub(hold[2],"1",results)
}
Upvotes: 0
Views: 105
Reputation: 24074
You can either define results
prior to your loop and modify your loop to make it write in the right row of results
at each turn:
results <- as.matrix(M)
for (i in 1:nrow(M)) {
hold <- unique(unlist(strsplit(unique(results[i, ]), "")))
hold <- hold[!is.na(hold)]
hold <- sort(hold)
results[i, ] <- gsub(hold[1], "0", results[i, ])
results[i, ] <- gsub(hold[2], "1", results[i, ])
}
Or use a slightly different approach with apply
and only sub
/ gsub
(I added the condition on length(u_lett)
because the first row of example data only has 1 letter):
results <- t(apply(M, 1,
function(x) {
u_lett <- sort(unique(c(sub("([A-Z])[A-Z]", "\\1", x), sub("[A-Z]([A-Z])", "\\1", x))))
x <- gsub(u_lett[1], "0", x)
if (length(u_lett)>1) x <- gsub(u_lett[2], "1", x)
x
}))
results
# id1 id2 id3 id4 id5 id6 id7 id8 id9
#[1,] "00" "00" "00" "00" "00" "00" "00" "00" "00"
#[2,] "01" "01" "00" "01" "11" "01" "01" "01" "01"
#[3,] "00" "00" "01" "01" "00" "11" "11" "11" "01"
#[4,] "01" "11" "01" "00" "11" "11" "11" "01" "00"
Or you can mix both to get a loop
/sub
-gsub
or a apply
/strsplit
solution...
Upvotes: 3