0

I am trans-code from matlab to r. I have code which is c-like structure in matlab.

for i = 1:m0                       
    Ent(i).connums = m0 - 1;        % number of neighbours
    Ent(i).con = [1:i-1 i+1:m0]';   % neighbour list
    Ent(i).H = [];                  
    Ent(i).L = [];                  
end 

Ent in code above is a c like structure array. I am trying to store a graph as adjacent list. In r, I was trying to use a list of lists. Say, Ent is a list of lists includes nodes. Sublists in Ent is a list including a node detail information.

What I tried:

rm(list = setdiff(ls(), lsf.str()))
m0<-4
Ent <- list()

for (i in seq(1, m0))                       
{
    connums <- m0 - 1                       
    if (i + 1 > m0)                             
    {
        con <- seq(1,i-1)
    }
    else if (i - 1 < 1)
    {
        con <- c(seq(i+1,m0))
    }
    else
    {
        con <- c(seq(1,i-1), seq(i+1,m0))
    }

    H <- 0                             
    L <- 0                              
    Ent <- c(Ent, list(n=i, connums=connums, con=con, H=H, L=L))
}
Ent
is.list(Ent)
is.vector(Ent)
print(length(Ent))

for (f in Ent)
{
    print(f)
}

the results:

> Ent
$n
[1] 1

$connums
[1] 3

$con
[1] 2 3 4

$H
[1] 0

$L
[1] 0

$n
[1] 2

$connums
[1] 3

$con
[1] 1 3 4

$H
[1] 0

$L
[1] 0

$n
[1] 3

$connums
[1] 3

$con
[1] 1 2 4

$H
[1] 0

$L
[1] 0

$n
[1] 4

$connums
[1] 3

$con
[1] 1 2 3

$H
[1] 0

$L
[1] 0

> is.list(Ent)
[1] TRUE
> is.vector(Ent)
[1] TRUE
> print(length(Ent))
[1] 20
> for (f in Ent)
+ {
+ print(f)
+ }
[1] 1
[1] 3
[1] 2 3 4
[1] 0
[1] 0
[1] 2
[1] 3
[1] 1 3 4
[1] 0
[1] 0
[1] 3
[1] 3
[1] 1 2 4
[1] 0
[1] 0
[1] 4
[1] 3
[1] 1 2 3
[1] 0
[1] 0

Why the length of Ent is 20? The list seems be unlist. My expected result might be sublists in a list. The length of Ent of sublist should be 4. I've read this solution and I still cant find my solution. Is it possible to store c like structure in r? how to do that? Any alternative solutions?

Community
  • 1
  • 1
Nick Dong
  • 3,638
  • 8
  • 47
  • 84

1 Answers1

1

The length of the list is 20 because of Ent <- c(Ent, list(n=i, connums=connums, con=con, H=H, L=L)). Here you concatenate the list to the previous list. You do not concatenate the specific elements of the lists to eachother. Thus if Ent has length 0, 5 gets added. This happens 4 times (since length(seq(1, m0)) = 4), and 4*5 = 20. If you want to append to a specific elemnt in Ent, you could try:

Ent$H = c(Ent$H, ...) # replace ... with values to append
Ent$L = c(Ent$L, ...)
Vandenman
  • 3,046
  • 20
  • 33
  • It is a good alternative way for Ent$H. What about Ent$con? It is not a value; it is a sequence. – Nick Dong Apr 03 '17 at 08:39
  • Assuming that the sequence always has the same length, you could try `Ent$con = rbind(Ent$con, con)` which binds it into a matrix. If it doesn't always have the same length you could make it a nested list, where `Ent$con` is a list and `Ent$con[[1]]` is the first sequence, `Ent$con[[2]]` is the second, etc. This you could do via `Ent$con = c(list(Ent$con), list(con))`. – Vandenman Apr 03 '17 at 08:50
  • The length of con is not fixed. `Ent$con = c(list(Ent$con), list(con))` could not get the expected result. `a<-list(1,2) ;a<-c(list(a),list(list(3,4))) ;a<-c(list(a),list(list(5,6))) `. No matter how many ways I try, it could not get the expected result. I re-view the question [Append an object to a list in R in amortized constant time, O(1)](http://stackoverflow.com/questions/2436688/append-an-object-to-a-list-in-r-in-amortized-constant-time-o1) . `a<-list(); a[[length(a)+1]] <- list(5,6)` should works in a low efficiency way. Anyway it works. – Nick Dong Apr 03 '17 at 09:34
  • 1
    This seems to work though: `Ent = list(con = list(1:3)); con = 2:4; Ent$con = c(Ent$con, list(con)); con = 3:5; Ent$con = c(Ent$con, list(con))`. – Vandenman Apr 03 '17 at 09:42
  • Yes, list->sublist->vector. Ent->con->1:3 .Thanks @Vandenman That should r-style code. – Nick Dong Apr 03 '17 at 11:18