Search code examples
rparsingeval

Error: Target of assignment expands to non-language object, when using eval(parse())


Example Data

df <- structure(list(Date = structure(c(15706, 15707, 15708, 15709, 
15712, 15713, 15714, 15715, 15716, 15719), class = "Date"), MidPrs_JPY = c(NA, 
NA, NA, 0.00102, 0.00102, 0.00102, 0.00102, 0.00102, 0.00102, 
NA), BID_EUR = c(NA, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 1e-04, 
2e-04, 2e-04, 2e-04), ASK_EUR = c(NA, -2e-04, -3e-04, -7e-04, 
-3e-04, -4e-04, -4e-04, -7e-04, -5e-04, -5e-04), BID_GBP = c(NA, 
0.0048, 0.0048, 0.0048, 0.0048, 0.0048, 0.0048, 0.0048, 0.0048, 
0.0048), ASK_GBP = c(NA, 0.0042, 0.0042, 0.0042, 0.0042, 0.0042, 
0.0042, 0.0042, 0.0042, 0.0042), BID_USD = c(0.0034, 0.0034, 
0.0034, 0.0034, 0.0034, 0.0034, 0.0034, 0.0034, 0.0034, 0.0034
), ASK_USD = c(0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 0.003, 
0.003, 0.003, 0.003)), row.names = c(NA, 10L), class = "data.frame")

namesV <- c("EUR", "GBP", "USD")

Question

When playing around with eval(parse(...)) while writing a loop I noticed that one is not able to assign to a statement resulting from eval(parse(...)). This does not make sense to me since one can call a column by using this method but apparently can not assign new values.

What I mean by not being able to assign but call:

eval(parse(text = paste0("RepoCal$BID_", namesV[1])))

Allows me to call the column, however:

eval(parse(text = paste0("Repomid$MidPrs_", namesV[1]))) <- eval(parse(text = paste0("Repomid$MidPrs_", namesV[2])))

results in the Error:

target of assignment expands to non-language object

I am grateful for any tips that would help me to understand the underlying problem or even solve it, thanks!


Solution

  • The error message is obscure but what this essentially tells us is that you can’t perform assignments to arbitrary expressions. eval(parse(…)) isn’t a name, you can’t assign to it.1

    The fundamental problem you want to solve doesn’t require any of that, luckily (because otherwise you’d be in a right pickle). Instead, you need to perform [[ subsetting rather than $ subsetting:

    Repomid[[paste0('MidPrs_', namesV[1L])]] <- Repomid[[paste0('MidPrs_', namesV[2L])]]
    

    Simply put, the syntactic form foo[['bar']] is (more or less) equivalent to foo$bar, where bar is a quoted string in the first expression, but an unquoted name in the second one.


    1 It’s (quite a lot) more complicated than that, because you can assign to expressions in R which aren’t pure names. But ultimately they all need to resolve to a name somehow. The above doesn’t. But even if it did it probably wouldn’t work as you’d expect because you’re attempting to assign to the result of that eval call. And the result of that eval call is a value, not a name. R fundamentally doesn’t allow assigning to values.