Question

So I have a table m, consisting of a random number of rows and columns. (can be any size)...

I want to do this calculation against each rows/columns totals:

  r[i] * c[j] / n;

Where r <- rowSums(m);, c <- colSums(m); and n <- sum(m);

I can do it with a double for-loop but I'm hoping to implement it now using while loops.

I wasn't going to use while loops but seems the table size can differ, I figured it was wise too.

I'm storing each value as it's found in a test vector.

This is my attempt, but I'm messing up the indices:

while(i < nrow(m)){
    while(j < ncol(m)){
        test[i] <- r[i]*c[j] / n;
        j=j+1;
        i=i+1;
    }
    j=j+1;
    i=i+1;
}

Any guidance to help me sort out my loops would be much appreciated. Thanks in advance.

update

See below for an example and expected result:

    m <- t(matrix(c(28,48,10,114), nrow=2, ncol=2));
    r <- rowSums(m); #76 124 (sum of rows)
    c <- colSums(m); #38 162 (sum of cols)
    n <- sum(m);     #200 (sum of all cells)

    test <- c(0, times length(m)); #empty vector/data frame

    #inside while loops, calc for each r and c indice:
    test[1] <- 76 *38 /200 #first calc to test[i] where i=1
    test[2] <- 124*38 /200
    test[3] <- 76*162 /200
    test[4] <- 124*162/200 #last calc to test[i] where i==length(m)
Was it helpful?

Solution 2

No need to use a while loop. It is always best to use vector operations in R (and any other array-based language). It makes for clearer and faster code.

nrows<-sample(1:100,1) # a random number of rows
ncols<-sample(1:100,1) # a random number of columns

#create a matrix of random numbers with our random dimnesions
m<-matrix(runif(nrows*ncols), nrow=nrows) 
n<-sum(m)
#read into outer, it creates a cartesian product of your vectors
#so you will have every r[i] multipled with every r[j]...ie what your loop is doing
r<-outer(rowSums(m),colSums(m),function(x,y) x*y/n)

Hope this helps, let me know if you have any questions.

OTHER TIPS

I would avoid using a for or while loop and do something like this instead:

> as.vector(outer(r,c, function(x,y) x*y/n))
[1]  14.44  23.56  61.56 100.44

A more R-like solution would be to use expand.grid instead of a nested while loop:

Set-up:

> m <- matrix(1:12, 3, 4)
> m
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> n <- sum(m)
> r <- rowSums(m)
> c <- colSums(m)

Now:

> test <- expand.grid(r,c)
> test
   Var1 Var2
1    22    6
2    26    6
3    30    6
4    22   15
5    26   15
6    30   15
7    22   24
8    26   24
9    30   24
10   22   33
11   26   33
12   30   33
> test <- test[,1] * test[,2] / n
> test
 [1]  1.692308  2.000000  2.307692  4.230769  5.000000  5.769231  6.769231
 [8]  8.000000  9.230769  9.307692 11.000000 12.692308
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top