1

I am trying to create a nested list where the value from one vector becomes the name and the process repeats until the last vector which stores an actual value. I was thinking that the code I have below would work, but it isn't

chips[[toString(aCor[i])]]=list(toString(bCor[i])=list(toString(cCor[i])=list(toString(dCor[i])=eCor[i])))

I was expecting something like this if aCor=c(1,2,2,1), bCor=c(4,5,6,4), cCor=c(3,3,2,3), dCor=c(1,4,5,1), eCor=c(1,3,4,7)

Resulting list ["1"=["4"=["3"=["1"= 7]]], "2"=["5"=["3"=["4"=3]],"6"=["2"=["5"=4]]]]

$1
$1$4
$1$4$3
$1$4$3$1
[1] 7

$2
$2$5
$2$5$3
$1$4$3$4
[1] 3

$2
$2$6
$2$6$2
$1$6$2$5
[1] 4

Sorry if the expected list is formatted poorly. I wasnt sure the best way to do it. If there is a better way of doing this than a list I am open to suggestions, I would have used a dictionary in python and this was the closest I could find that would replicate it. I am currently getting this error

Error in parse(text = script) : parse error in text argument: unexpected '=' in function argument before

  • Please show a small reproducible example with `dput` – akrun Aug 06 '20 at 06:35
  • @akrun I am currently getting this error so I cant give a reproducible example Error in parse(text = script) : parse error in text argument: unexpected '=' in function argument before – Nikita Belooussov Aug 06 '20 at 06:37
  • It is just to understand what your input and expected would be – akrun Aug 06 '20 at 06:38
  • @akrun I have that. it is the 2 paragraphs before the end – Nikita Belooussov Aug 06 '20 at 06:39
  • Perhaps you need `setNames` – akrun Aug 06 '20 at 06:39
  • @akrun how would that work? My only experience with setNames is with already existing lists. Not using it to create ones – Nikita Belooussov Aug 06 '20 at 06:41
  • I posted a simple example below as solution. I don't have the input data from your side to test it. – akrun Aug 06 '20 at 06:43
  • You do have the input though. I listed the vectors after the first line of code. @akrun – Nikita Belooussov Aug 06 '20 at 06:45
  • Is this the input `I was expecting something like this if aCor=[1,2,2,1], bCor=[4,5,6,4], cCor=[3,3,2,3], dCor=[1,4,5,1], eCor=[1,3,4,7]` and what is the expected? the `list` you showed is a python list format – akrun Aug 06 '20 at 06:46
  • yes and this is the expected ["1"=["4"=["3"=["1"= 7]]], "2"=["5"=["3"=["4"=3]],"6"=["2"=["5"=4]]]] – Nikita Belooussov Aug 06 '20 at 06:46
  • the format is a bit confusing because you may be mixing python format with R – akrun Aug 06 '20 at 06:47
  • sorry if it was unclear, feel free to reformat the givens so that it is easier to understand. I did it the best way I thought – Nikita Belooussov Aug 06 '20 at 06:47
  • Can you show the `dput(aCor)`, `dput(bCor)` etc. – akrun Aug 06 '20 at 06:48
  • Yeah sorry, I prefer coding in python and am more used to writing in python. I changed the input vectors to be closer to r. The output would be just the vectors of numbers? – Nikita Belooussov Aug 06 '20 at 06:50
  • I understand the input vector, aCor, bCor, but it is the expected that is not clear `["1"=["4"=["3"=["1"= 7]]], "2"=["5"=["3"=["4"=3]],"6"=["2"=["5"=4]]]]` – akrun Aug 06 '20 at 06:52
  • Based on the input showed, should the value be `["1"=["4"=["3"=["1"= 1]]]` instead of `7` – akrun Aug 06 '20 at 06:54
  • Perhaps you meant `lst(!! as.character(aCor[1]) := lst(!! as.character(bCor[1]) := lst(!! as.character(cCor[1]) := lst(!! as.character(dCor[1]) := eCor[1]))))` – akrun Aug 06 '20 at 06:57
  • @akrun I have updated the expected output based off of what you given me. I was just trying to show the structure of the list that I wanted as well and not just give a single number as an output. I have also updated it to be 7, you might have not noticed before. – Nikita Belooussov Aug 06 '20 at 07:01
  • Your `eCor <- c(1,3,4,7)` I expect the 1st value to be 7 – akrun Aug 06 '20 at 07:03
  • no it is 1, it is 7 in the output because the values in the other vectors are the same so it gets overwritten from 1 to 7 – Nikita Belooussov Aug 06 '20 at 07:06
  • 1
    Would this be helpful? https://stackoverflow.com/questions/52872581/nested-list-based-on-flat-condensed-name-structure-of-named-vector-or-list/ – Ronak Shah Aug 06 '20 at 07:31
  • @RonakShah yes i just need it to be with vectors instead of a string but I will see if I can get it working also i need it just make one overall dictionary not two – Nikita Belooussov Aug 06 '20 at 07:56
  • @NikitaBelooussov i updated the solution. Please check – akrun Aug 06 '20 at 08:05

2 Answers2

2

We could use lst from purrr or dplyr (or need setNames) which would work with assignment (:=)

nm1 <- 'a'
nm2 <- 'b'
dplyr::lst(!! nm1 := lst(!! nm2 := 5))
#$a
#$a$b
#[1] 5

If we need to create a nested list, use a for loop

lst1 <- list()

for(i in seq_along(aCor)) {
      an <- as.character(aCor[i])
      
      bn <- as.character(bCor[i])
      cn <- as.character(cCor[i])
      dn <- as.character(dCor[i])
      lst1[[an]][[bn]][[cn]][[dn]] <- eCor[[i]]
      

}

-output

lst1
#$`1`
#$`1`$`4`
#$`1`$`4`$`3`
#$`1`$`4`$`3`$`1`
#[1] 7




#$`2`
#$`2`$`5`
#$`2`$`5`$`3`
#$`2`$`5`$`3`$`4`
#[1] 3



#$`2`$`6`
#$`2`$`6`$`2`
#$`2`$`6`$`2`$`5`
#[1] 4

data

aCor <- c(1,2,2,1)
bCor <- c(4,5,6,4)
cCor <- c(3,3,2,3)
dCor <- c(1,4,5,1)
eCor <- c(1,3,4,7)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • why are you using := instead of = and why the !! – Nikita Belooussov Aug 06 '20 at 07:03
  • @NikitaBelooussov The `=` won't evaluate an object it would give `list(nm1 = 5)` – akrun Aug 06 '20 at 07:04
  • and the !! does what? – Nikita Belooussov Aug 06 '20 at 07:06
  • It evaluates the object – akrun Aug 06 '20 at 07:08
  • I tried to do it this way just now and got this error: Error in `*tmp*`[[bn]] : subscript out of bounds Execution halted – Nikita Belooussov Aug 06 '20 at 08:08
  • @NikitaBelooussov I showed the input data as well. Can you test using that. I am not getting any error with that – akrun Aug 06 '20 at 08:08
  • https://rdrr.io/snippets/, I am using this website just because it is easier to test code right now for me. I am not sure if that could be the issue and I am using the input you are using – Nikita Belooussov Aug 06 '20 at 08:09
  • @NikitaBelooussov can you run the code on R console in your syste – akrun Aug 06 '20 at 08:10
  • @NikitaBelooussov i get the error in that website. May be it is parsing differently? – akrun Aug 06 '20 at 08:11
  • the issue is that I am using a different program called spotfire and it allows to create r functions. It is also giving me the same error. Your first method seemed to work, I am just trying to find a way to make it work in a for loop – Nikita Belooussov Aug 06 '20 at 08:19
  • @NikitaBelooussov may be it is a parsing issue. I am using R 4.0.2 – akrun Aug 06 '20 at 08:20
  • @NikitaBelooussov You could use the first method as `lst(!! an1[1] := lst(!! bn1[1] := lst(!! cn1[1] := lst(!! dn1[1] := eCor[1]))))`, but it still needs a `for` loop for updating via names . here `an1 <- as.character(aCor); bn1 <- as.character(bCor); cn1 <- as.character(cCor); dn1 <- as.character(dCor)` – akrun Aug 06 '20 at 08:25
  • 1
    Thanks for your help. I am not sure why your code didnt work, I put up the code that seems like it is going to work in my case – Nikita Belooussov Aug 06 '20 at 08:46
1

This is the code I ended up making with the help of akrun in this question and another code that I found on this page written by IRTFM.

require(dplyr)

aCor <- c(1,2,2,1)
bCor <- c(4,5,6,4)
cCor <- c(3,3,2,3) 
dCor <- c(1,4,5,1)
eCor <- c(1,3,4,7)

appendList <- function (x, val) 
{
   stopifnot(is.list(x), is.list(val))
   xnames <- names(x)
   for (v in names(val)) {
      x[[v]] <- if (v %in% xnames && is.list(x[[v]]) && is.list(val[[v]])) 
        appendList(x[[v]], val[[v]])
        else c(val[[v]])
    }
   x
}


chips <- list()

for(i in seq_along(aCor)) {
   an <- as.character(aCor[i]) 
   bn <- as.character(bCor[i])
   cn <- as.character(cCor[i])
   dn <- as.character(dCor[i])
   #chips[[an]]=lst(!! bn := lst(!! cn := lst(!! dn := eCor[i])))
   list1=lst(!! an := lst(!! bn := lst(!! cn  := lst(!! dn:= eCor[i]))))
   chips=appendList(chips,list1)
}

chips

Output:

$1
$1$4
$1$4$3
$1$4$3$1
[1] 7

$`2`
$`2`$`5`
$`2`$`5`$`3`
$`2`$`5`$`3`$`4`
[1] 3

$`2`$`6`
$`2`$`6`$`2`
$`2`$`6`$`2`$`5`
[1] 4