shadow
shadow

Reputation: 22323

iteratively adding elements to list in one step

I would like to add list elements iteratively in R, so that later elements can use the elements created earlier. The desired behavior is as follows:

lst <- list(a = 1, 
            b = 2, 
            c = b)
lst
## $a
## [1] 1
## 
## $b
## [1] 2
## 
## $c
## [1] 2

I know that I can easily accomplish the same using e.g.

lst <- list(a = 1, 
            b = 2)
lst[['c']] <- lst[['b']]

But I was wondering, if I could do this in one step.

Upvotes: 5

Views: 527

Answers (3)

shadow
shadow

Reputation: 22323

Update: This is now possible with the lst function of the tibble package:

tibble::lst(a = 1, b = 2, c = b)
## $a
## [1] 1
## 
## $b
## [1] 2
## 
## $c
## [1] 2

My previous workaround was using mutate from plyr:

mylist <- function(...) plyr::mutate(.data=list(), ...)

mylist(a = 1, 
       b = 2, 
       c = b)
## $a
## [1] 1
## 
## $b
## [1] 2
## 
## $c
## [1] 2

Upvotes: 5

alexis_laz
alexis_laz

Reputation: 13122

A more classic idea:

mylist = function(...) 
{
    args = as.list(substitute(list(...)))[-1]    
    lapply(args, eval, envir = args)
}
mylist(a = 1, b = 2, c = a + b)
#$a
#[1] 1
#
#$b
#[1] 2
#
#$c
#[1] 3

For a strict iterative approach, a loop is needed:

mylist = function(...)
{
    args = as.list(substitute(list(...)))[-1]
    for(i in seq_along(args)) args[[i]] = eval(args[[i]], envir = args)
    return(args)
}
mylist(a = 1, b = a + 1, c = b + 1)
#$a
#[1] 1
#
#$b
#[1] 2
#
#$c
#[1] 3

Upvotes: 2

lukeA
lukeA

Reputation: 54237

Here's another way

rev(within(list(), { a = 1; b = 2; c = b }))
# $a
# [1] 1
# 
# $b
# [1] 2
# 
# $c
# [1] 2

Upvotes: 6

Related Questions