Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create additional row if there are specific values in the row

Tags:

r

The matrix which I have:

> dput(head(data1))
structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 1, 0, 1, 0, 0), .Dim = c(6L, 18L), .Dimnames = list(c("AT1G01050", 
"AT1G01080", "AT1G01090", "AT1G01320", "AT1G01470", "AT1G01800"
), c("10", "33.95", "58.66", "84.42", "110.21", "134.16", "164.69", 
"199.1", "234.35", "257.19", "361.84", "432.74", "506.34", "581.46", 
"651.71", "732.59", "817.56", "896.24")))

To make it easier to explain I will show the table below:

          10 33.95 58.66 84.42 110.21 134.16 164.69 199.1 234.35 257.19 361.84 432.74 506.34 581.46 651.71 732.59 817.56 896.24
AT1G01050  0     0     0     0      0      0      0     0      1      0      0      0      0      1      0      0      0      0
AT1G01080  0     0     0     0      1      0      1     0      1      0      1      0      0      1      0      1      0      1
AT1G01090  0     0     0     0      0      0      0     0      0      0      1      0      0      1      0      1      0      0
AT1G01320  0     0     0     0      0      0      0     0      0      0      0      1      0      1      0      1      0      1
AT1G01470  0     0     0     1      0      0      0     0      0      0      0      0      0      0      0      0      0      0
AT1G01800  0     0     0     1      0      0      0     0      0      1      0      0      0      0      0      0      0      0

As you see my table is full of 0 and 1. There is in many cases more than one 1 in each row. So what I would like to do is duplicate/triplicate the rows just to leave a single 1 in each row. So for Example take a first row:

          10 33.95 58.66 84.42 110.21 134.16 164.69 199.1 234.35 257.19 361.84 432.74 506.34 581.46 651.71 732.59 817.56 896.24
AT1G01050  0     0     0     0      0      0      0     0      1      0      0      0      0      1      0      0      0      0

There are two number 1 in this row. That means I have to create one more row for this "gene". So the output should look like that. I leave first 1 (starting from the left) in the data but remove the second. To distinguish later we have to change the name of the row as well:

                10 33.95 58.66 84.42 110.21 134.16 164.69 199.1 234.35 257.19 361.84 432.74 506.34 581.46 651.71 732.59 817.56 896.24
    AT1G01050_1  0     0     0     0      0      0      0     0      1      0      0      0      0      0      0      0      0      0

Now I remove first 1 and leave the second.

                10 33.95 58.66 84.42 110.21 134.16 164.69 199.1 234.35 257.19 361.84 432.74 506.34 581.46 651.71 732.59 817.56 896.24
    AT1G01050_2  0     0     0     0      0      0      0     0      0      0      0      0      0      1      0      0      0      0

I believe it's not easy to do but I believe that one of you may have any idea how to solve that problem.

like image 586
Rechlay Avatar asked Mar 17 '23 14:03

Rechlay


2 Answers

Try this:

divideLine = function(u)
{
    index = which(u %in% 1)
    len = length(u)

    if(sum(u)<=1) return(t(u))

    t(mapply(function(x,y){vec=rep(0, len);vec[y]=1;vec}, 1:length(index), index))
}

lst = apply(mat,1,divideLine)
x = lapply(lst, nrow)

res = do.call(rbind, lst)
rownames(res)=unlist(Map(function(u,v) paste(v, as.character((1:u)-1), sep='_'),x, names(x)))

#> res
#            10 33.95 58.66 84.42 110.21 134.16 164.69 199.1 234.35 257.19 361.84 432.74 506.34 581.46 651.71 732.59 817.56 896.24
#AT1G01050_0  0     0     0     0      0      0      0     0      1      0      0      0      0      0      0      0      0      0
#AT1G01050_1  0     0     0     0      0      0      0     0      0      0      0      0      0      1      0      0      0      0
#AT1G01080_0  0     0     0     0      1      0      0     0      0      0      0      0      0      0      0      0      0      0
#AT1G01080_1  0     0     0     0      0      0      1     0      0      0      0      0      0      0      0      0      0      0
#AT1G01080_2  0     0     0     0      0      0      0     0      1      0      0      0      0      0      0      0      0      0
#AT1G01080_3  0     0     0     0      0      0      0     0      0      0      1      0      0      0      0      0      0      0
#AT1G01080_4  0     0     0     0      0      0      0     0      0      0      0      0      0      1      0      0      0      0
#AT1G01080_5  0     0     0     0      0      0      0     0      0      0      0      0      0      0      0      1      0      0
#AT1G01080_6  0     0     0     0      0      0      0     0      0      0      0      0      0      0      0      0      0      1
#AT1G01090_0  0     0     0     0      0      0      0     0      0      0      1      0      0      0      0      0      0      0
#AT1G01090_1  0     0     0     0      0      0      0     0      0      0      0      0      0      1      0      0      0      0
#AT1G01090_2  0     0     0     0      0      0      0     0      0      0      0      0      0      0      0      1      0      0
#AT1G01320_0  0     0     0     0      0      0      0     0      0      0      0      1      0      0      0      0      0      0
#AT1G01320_1  0     0     0     0      0      0      0     0      0      0      0      0      0      1      0      0      0      0
#AT1G01320_2  0     0     0     0      0      0      0     0      0      0      0      0      0      0      0      1      0      0
#AT1G01320_3  0     0     0     0      0      0      0     0      0      0      0      0      0      0      0      0      0      1
#AT1G01470_0  0     0     0     1      0      0      0     0      0      0      0      0      0      0      0      0      0      0
#AT1G01800_0  0     0     0     1      0      0      0     0      0      0      0      0      0      0      0      0      0      0
#AT1G01800_1  0     0     0     0      0      0      0     0      0      1      0      0      0      0      0      0      0      0
like image 134
Colonel Beauvel Avatar answered Apr 30 '23 21:04

Colonel Beauvel


May be this helps:

indx <- rep(1:nrow(data1),  rowSums(data1!=0))
res <- do.call(rbind, lapply(split(indx, indx), function(i) {
             x1 <- data1[i,,drop=FALSE]
             indx2 <- colSums(x1!=0)==nrow(x1)
             x2 <- x1[,indx2]
           if(is.matrix(x2)) {
                 x2[lower.tri(x2)|upper.tri(x2)] <- 0
                 }
             x1[,indx2] <- x2
             x1  }))
  row.names(res) <- make.names(row.names(res),unique=TRUE)

RESULT:

 res
 #            10 33.95 58.66 84.42 110.21 134.16 164.69 199.1 234.35   257.19
 #AT1G01050    0     0     0     0      0      0      0     0      1      0
 #AT1G01050.1  0     0     0     0      0      0      0     0      0      0
 #AT1G01080    0     0     0     0      1      0      0     0      0      0
 #AT1G01080.1  0     0     0     0      0      0      1     0      0      0
 #AT1G01080.2  0     0     0     0      0      0      0     0      1      0
 #AT1G01080.3  0     0     0     0      0      0      0     0      0      0
 #AT1G01080.4  0     0     0     0      0      0      0     0      0      0
 #AT1G01080.5  0     0     0     0      0      0      0     0      0      0
 #AT1G01080.6  0     0     0     0      0      0      0     0      0      0
 #AT1G01090    0     0     0     0      0      0      0     0      0      0
 #AT1G01090.1  0     0     0     0      0      0      0     0      0      0
 #AT1G01090.2  0     0     0     0      0      0      0     0      0      0
 #AT1G01320    0     0     0     0      0      0      0     0      0      0
 #AT1G01320.1  0     0     0     0      0      0      0     0      0      0
 #AT1G01320.2  0     0     0     0      0      0      0     0      0      0
 #AT1G01320.3  0     0     0     0      0      0      0     0      0      0
 #AT1G01470    0     0     0     1      0      0      0     0      0      0
 #AT1G01800    0     0     0     1      0      0      0     0      0      0
 #AT1G01800.1  0     0     0     0      0      0      0     0      0      1
 #            361.84 432.74 506.34 581.46 651.71 732.59 817.56 896.24
 #AT1G01050        0      0      0      0      0      0      0      0
 #AT1G01050.1      0      0      0      1      0      0      0      0
 #AT1G01080        0      0      0      0      0      0      0      0
 #AT1G01080.1      0      0      0      0      0      0      0      0
 #AT1G01080.2      0      0      0      0      0      0      0      0
 #AT1G01080.3      1      0      0      0      0      0      0      0
 #AT1G01080.4      0      0      0      1      0      0      0      0
 #AT1G01080.5      0      0      0      0      0      1      0      0
 #AT1G01080.6      0      0      0      0      0      0      0      1
 #AT1G01090        1      0      0      0      0      0      0      0
 #AT1G01090.1      0      0      0      1      0      0      0      0
 #AT1G01090.2      0      0      0      0      0      1      0      0
 #AT1G01320        0      1      0      0      0      0      0      0
 #AT1G01320.1      0      0      0      1      0      0      0      0
 #AT1G01320.2      0      0      0      0      0      1      0      0
 #AT1G01320.3      0      0      0      0      0      0      0      1
 #AT1G01470        0      0      0      0      0      0      0      0
 #AT1G01800        0      0      0      0      0      0      0      0
 #AT1G01800.1      0      0      0      0      0      0      0      0
like image 21
akrun Avatar answered Apr 30 '23 21:04

akrun