Create list with looping

98 views Asked by At

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;
2

There are 2 answers

9
Henrik On BEST ANSWER

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)
1
IRTFM On

(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.