0

I have a i times j (ixj) dummy-matrix for rating events of companies, with i dates and j different companies. On a day where a rating occurs rating [i,j]=1 and 0 otherwise.

I want to create a list, which contains 4 sublist (1 for each of the 4 companies). Each sublist states the row numbers of the rating event of the specific company.

This is my code:

r<-list(); i=1;j=2;
for(j in 1:4){
    x<-list()
    for(i in 100){
        if(rating[i,j]!=0){
        x<-c(x,i)
        i=i+1
        }
        else{i=i+1}
    }
    r[[j]]<-x
    j=j+1
}

It is somehow not working, and I really can not figure out where the bug is. The x sublists are always empty. Could somebody help?

Thanks a lot!

Here is an example rating matrix:

 rating<-matrix(data = 0, nrow = (100), ncol = 4, dimnames=list(c(1:100), c(1:4)));
 rating[3,1]=1;rating[7,1]=1;rating[20,1]=1;rating[75,1]=1;
 rating[8,2]=1;rating[40,2]=1;rating[50,2]=1;rating[78,2]=1;
 rating[1,3]=1;rating[4,3]=1;rating[17,3]=1;rating[99,3]=1;
 rating[10,4]=1;rating[20,4]=1;rating[30,4]=1;rating[90,4]=1;
  • Every time you encounter `x<-list()` inside that j-indexed-loop, any previous value in `x` will be erased. You also should NOT change i inside the i-indexed-loop. The for-function will do it for you. – IRTFM Mar 17 '14 at 10:18
  • Hi, thanks for the help. I dont think this is the bug though: I want the x sublist to get overwritten, because in the second for loop all rating events of company j are stored in x. Then I add x to the list r, and start again for company j+1 (so x gets overwritten, but that does not matter, because its stored in r[[j]]. – user3428319 Mar 17 '14 at 10:20
  • 2
    Post a small subset of `rating` using `dput` – IRTFM Mar 17 '14 at 10:21
  • just did above, also adjusted the code to that matrix, so you can jost copy everything. thank you for your help!! – user3428319 Mar 17 '14 at 10:39

2 Answers2

3

You may try this:

set.seed(123)
m <- matrix(data = sample(c(0, 1), 16, replace = TRUE), ncol = 4,
            dimnames = list(date = 1:4, company = letters[1:4]))
m
#     company
# date a b c d
#    1 0 1 1 1
#    2 1 0 0 1
#    3 0 1 1 0
#    4 1 1 0 1

lapply(as.data.frame(m), function(x){
  which(x == 1)
})

# $a
# [1] 2 4
# 
# $b
# [1] 1 3 4
# 
# $c
# [1] 1 3
# 
# $d
# [1] 1 2 4

Update
Or more compact (thanks to @flodel!):

lapply(as.data.frame(m == 1), which)
Henrik
  • 65,555
  • 14
  • 143
  • 159
  • Perfect, thank you so much Henrik! I should learn to use functions instead of loops :) – user3428319 Mar 17 '14 at 10:49
  • 1
    more compact: `lapply(as.data.frame(m) == 1, which)` – flodel Mar 17 '14 at 11:03
  • @flodel, Thank you for your comment. I don't manage to get the same result with your code; instead of one element per company, I get a list with 16 elements. Maybe I miss something obvious here... – Henrik Mar 17 '14 at 11:24
  • interesting... make it `lapply(as.data.frame(m == 1), which)` then :-) Sorry I did not test before commenting. – flodel Mar 17 '14 at 13:48
  • @flodel, I added your alternative to the answer to make it more visible. Thanks for your suggestion! – Henrik Mar 17 '14 at 13:55
  • Hi @flodel and @Henrik, you helped me so well yesterday, could I ask you one more question (trying to figure this out since hours again..) since you seem to know functions really well. I have this code now: `myfunction2 <- function(y){ x<-cds1.R y <- y[y>0] if(!is.null(y)) x[-y] else x } rl<-lapply(rowind.all,myfunction2)` – user3428319 Mar 18 '14 at 16:26
  • cds1.R is a matrix with 1552rows and 153 columns. rowind.all is a list containing 153 other lists, where each of these 153 lists contains some index numbers (between 1 and 1552). What I am trying to do with the function: I want to create a list rl, which contains i=153 sublists. The sublists should contain all values from cds1.R[,i], except those listed in rowind.all[i]. – user3428319 Mar 18 '14 at 16:27
  • Sorry, I hope you can help me, otherwise I make a real forum request... thank you! – user3428319 Mar 18 '14 at 16:27
  • @user3428319, Thanks for your comment. It seems to me that it is better that you post a new question. Because you are new to SO, you may have a look [**here**](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610#5963610) to learn about creating small, reproducible examples. People are generally much more happy to help if you post a tiny dummy data set to play with. Cheers. – Henrik Mar 18 '14 at 19:14
0

(Leave for-loops behind.) If ratings really is a matrix or even if its a dataframe, then why not use rowSums:

r <- rowSums(rating) # accomplished the stated task more effectively.

# simple example: 
> rating <- matrix( rbinom(100, 1,prob=.5), 10)
> rating
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1    0    1    0    0    1    1    0    0     1
 [2,]    1    0    0    0    0    0    0    1    1     1
 [3,]    0    0    1    1    1    1    0    0    1     0
 [4,]    1    0    0    0    1    1    0    0    0     1
 [5,]    1    1    0    1    1    1    1    0    0     0
 [6,]    1    1    1    0    1    1    1    0    1     0
 [7,]    0    1    0    1    0    1    1    0    1     0
 [8,]    0    1    0    0    1    1    0    1    1     0
 [9,]    1    1    1    0    1    1    1    1    0     0
[10,]    0    1    0    0    1    0    0    1    0     1
> rowSums(rating)
 [1] 5 4 5 4 6 7 5 5 7 4
> rowSums(as.data.frame(rating))
 [1] 5 4 5 4 6 7 5 5 7 4

If it needs to be a list then just wrap as.list() around it.

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Hi, thanks for your help, but I need the row numbers of when the rating occurs, not the number of rating events. – user3428319 Mar 17 '14 at 10:45