Search code examples
reval

Assign value to indices of nested lists stored as strings in R


I have a dataframe of nested list indices, which have been stored as strings. To give a simplified example:

df1 <- data.frame(x = c("lst$x$y$a", "lst$x$y$b"), stringsAsFactors = F)

These are then coordinates for the following list:

lst <- list(x=list(y=list(a="foo",b="bar",c="")))

I'd like replace values or assign new values to these elements using the indices in df1.

One attempt was

do.call(`<-`, list(eval(parse(text = df1[1,1])), "somethingelse"))

but this doesn't seem tow work. Instead it assigns "something" to foo.

I'm not too happy with using eval(parse(text=)) (maintaining code will become a nightmare), but recognise I may have little choice.

Any tips welcome.


Solution

  • Let's consider 3 situations:

    Case 1

    do.call(`<-`, list("lst$x$y$a", "somethingelse"))
    

    This will create a new variable named lst$x$y$a in your workspace, so the following two commands will call different objects. (The former is the object you store in lst, and the latter is the new variable. You need to call it with backticks because its name will confuse R.)

    > lst$x$y$a   # [1] "foo"
    > `lst$x$y$a` # [1] "somethingelse"
    

    Case 2

    do.call(`<-`, list(parse(text = "lst$x$y$a"), "somethingelse"))
    

    You mostly get what you expect with this one but an error still occurs:

    invalid (do_set) left-hand side to assignment

    Let's check:

    > parse(text = "lst$x$y$a")  # expression(lst$x$y$a)
    

    It belongs to the class expression, and the operator <- seems not to accept this class to the left-hand side.


    Case 3

    This one will achieve what you want:

    do.call(`<-`, list(parse(text = "lst$x$y$a")[[1]], "somethingelse"))
    

    If put [[1]] behind an expression object, a call object will be extracted and take effect in the operator <-.

    > lst
    
    # $x
    # $x$y
    # $x$y$a
    # [1] "somethingelse"
    # 
    # $x$y$b
    # [1] "bar"
    # 
    # $x$y$c
    # [1] ""