Inline list assignment

This seems silly and I'm not sure why I haven't encountered it before, but what patterns/functions do folks here use for inline list element assignment within a magrittr-style pipeline?

Example: I want to inject a timestamp into some object:

x <- list(foo = 1:3)
x$dt <- lubridate::now()
f(x)  ## now go do something with x

But ideally I'd like to inject that timestamp like so (with some hypothesized inject function):

x %>% inject(dt = lubridate::now()) %>% f()

Purrr's assign_in function does this in a very nice 'plucky' way, but requires the location to already exist in the target data. (In the example above the dt element is novel, triggering an error in assign_in).

I can obviously write my own minimal wrapper to do this, but I'm curious if there's already a function or operator out there of which I'm just not aware. I'm a fan of the pluck semantics, so it would ideally follow that pattern and either replace the element's value or append the element (depending on whether or not the element exists already).

Hi @mmuurr,

This isn't a particularly elegant solution, but any infix operator can be used in prefix form to make it pipe-able, such as to do sub-assignment (i.e. assign a value to a list-item). For example:

library(magrittr)

x <- list(foo = 1:3)

# Equivalent to x$name <- "value"
x %>% 
  `$<-`("name", "value")
#> $foo
#> [1] 1 2 3
#> 
#> $name
#> [1] "value"

# Equivalent to x["name"] <- "value"
x %>% 
  `[<-`("name", "value")
#> $foo
#> [1] 1 2 3
#> 
#> $name
#> [1] "value"

# Equivalent to x[["name"]] <- "value"
x %>% 
  `[[<-`("name", "value")
#> $foo
#> [1] 1 2 3
#> 
#> $name
#> [1] "value"

package rlist has convenience function list.append

library(rlist)
library(magrittr)
library(lubridate)

x <- list(foo=1:3)
x %>% list.append(dt = now())

apparently its doing not much more than

x %>%  c( list(dt = now()))

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.