Donkeykongy
Donkeykongy

Reputation: 135

splitting integers and converting into matrix

I was wondering if is it possible to stringsplit each integer in a set of numbers and transform it into a transition matrix, e.g

data<-c(11,123,142,1423,1234,12)

What i would like to do is to split each integer in the data (considering only the first two elements in the dataset),first element will be 1,1 second element will be 1,2,3....and convert it into matrix e,g 1,1 will be 1 to 1, 1,2 will be 1 to 2 and 2,3 will be 2 to 3. generating the following matrix

   1 2 3 4 5 
1  1 1 0 0 0
2  0 0 1 0 0
3  0 0 0 0 0
4  0 0 0 0 0
5  0 0 0 0 0

My matrix will never go past 5x5. Below is what i have done which works but it's really really tedious.

data2<-as.matrix(as.character(data))
for(i in 1:nrow(data2)) {
values<-strsplit(data2,"")
}
values2<-t(sapply(values, '[', 1:max(sapply(values, length))))
values2[is.na(values2)]<-0
values3<-apply(values2,2,as.numeric)
from1to1<-0
from1to2<-0
from1to3<-0
from1to4<-0
from1to5<-0
from2to1<-0
from2to2<-0
from2to3<-0
from2to4<-0
...
from5to4<-0
from5to5<-0
for(i in 1:nrow(values3)){
  for(j in 1:(ncol(values3)-1))
if   (((values3[i,j]==1)&(values3[i,j+1]==1))){
  from1to1<-from1to1 + 1
}else{
  if   (((values3[i,j]==1)&(values3[i,j+1]==2))){
    from1to2<-from1to2 + 1
  }else{
    if   (((values3[i,j]==1)&(values3[i,j+1]==3))){
      from1to3<-from1to3 + 1
    }else{
      if   (((values3[i,j]==1)&(values3[i,j+1]==4))){
        from1to4<-from1to4 + 1
      }else{
        if   (((values3[i,j]==1)&(values3[i,j+1]==5))){
          from1to5<-from1to5 + 1
        }else{
          if   (((values3[i,j]==1)&(values3[i,j+1]==1))){
            from1to1<-from1to1 + 1
          }else{.....continues through all other from2to1...from5to5``

I then place every single number into a 5x5 matrix.

This is obviously tedious and long and ridiculous. Is there anyway to shorten this? Any suggestions is appreciated.

Upvotes: 1

Views: 128

Answers (1)

alistaire
alistaire

Reputation: 43334

Here's an option, presented here piped so as to be easy to follow:

library(magrittr)    # for the pipe

# initialize a matrix of zeros
mat <- matrix(0, 5, 5)

# split each element into individual digits
strsplit(as.character(data), '') %>% 
    # turn list elements back to integers
    lapply(as.integer) %>% 
    # make a 2 column matrix of each digit paired with the previous digit
    lapply(function(x){matrix(c(x[-length(x)], x[-1]), ncol = 2)}) %>%
    # reduce list to a single 2-column matrix
    do.call(rbind, .) %>% 
    # for each row, add 1 to the element of mat they subset
    apply(1, function(x){mat[x[1], x[2]] <<- mat[x[1], x[2]] + 1; x})
# output is the transpose of the matrix; the real results are stored in mat
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
## [1,]    1    1    2    1    4    1    4    2    1     2     3     1
## [2,]    1    2    3    4    2    4    2    3    2     3     4     2

mat
##      [,1] [,2] [,3] [,4] [,5]
## [1,]    1    3    0    2    0
## [2,]    0    0    3    0    0
## [3,]    0    0    0    1    0
## [4,]    0    2    0    0    0
## [5,]    0    0    0    0    0

Alternately, if you'd like xtabs as suggested by alexis_laz, replace the last line with xtabs(formula = ~ .[,1] + .[,2]) instead of using mat.

You might also check out the permutations package, which from what I can tell seems to be for working with this kind of data, though it's somewhat high-level.

Upvotes: 1

Related Questions