0

I'm creating variables based on certain string combinations. Each variable would store some values. In this example, to make it simple, they store a numerical value. However, in actual problem, each would store a tibble.

I need to store each tibble as RData and they have to be created using unique combinations of the string.

The problem is when I use save() on this variable, it couldn't find it so the save would fail.


res <- 12345
sku = 'sku_a'
index = '1'
# create variable based on string combination
# assign variable value with res
assign(paste0(index,'_arima_',sku), res) 

# return the value of the created variable
get(paste0(index,'_arima_',sku))

# save created variable as RData
save(paste0(index,'_arima_',sku), file = paste0(index,'_arima_',sku,'.RData'))
Error in save(paste0(index, "_arima_", sku), file = paste0(index, "_arima_",  : 
  object ‘paste0(index, "_arima_", sku)’ not found

save(get(paste0(index,'_arima_',sku)), file = paste0(index,'_arima_',sku,'.RData'))
Error in save(get(paste0(index, "_arima_", sku)), file = paste0(index,  : 
  object ‘get(paste0(index, "_arima_", sku))’ not found

save(eval(paste0(index,'_arima_',sku)), file = paste0(index,'_arima_',sku,'.RData'))
Error in save(eval(paste0(index, "_arima_", sku)), file = paste0(index,  : 
  object ‘eval(paste0(index, "_arima_", sku))’ not found

5
  • You need a get in your save command. Even better, forget assign (for now) and learn to use lists instead of this assign/get coding nightmare. Commented Jun 25, 2020 at 11:56
  • Actually I have no choice but use assign here because of some server issues. Basically the server will randomly crash and I would lose all the previous results unless I store each result from each iteration. And then continue back from the last point when it crashed. I used get() in the second option above, not sure if you can see it. save(get(object)) Commented Jun 25, 2020 at 12:00
  • @Roland a get in the save command doesn't help here. The first argument of save seems to be captured without being evaluated at all. Your second point is of course spot on. Commented Jun 25, 2020 at 12:15
  • You can store the results of the iterations in a list just the same as you can store them in the global environment. There is really no reason to use assign in R unless you need fine-control regarding the environment objects are assigned to. You do not have such a case. Commented Jun 25, 2020 at 13:08
  • @Roland in the actual code, the results are stored in a list. But the problem with the list is that if the server crashes for whatever reason, the list object will be lost. Hence, I've to rerun the whole loop again. It's probably better if I can save the updated list object at every iteration, instead of saving the result of each iteration in a separate object. Commented Jun 26, 2020 at 1:09

2 Answers 2

2

The first argument of save which is the ... operator is captured unevaluated, so it seems you can't put an expression here. One quick way round this if you have magrittr or dplyr loaded is to use the pipe, which will work:

paste0(index,'_arima_',sku) %>% save(file = paste0(index,'_arima_',sku,'.RData'))

Note though that an added complexity is that variable names shouldn't start with a digit in R. In your case, the variable can only be got from the console by '1_arima_sku_a' (i.e. it needs to be quoted)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Allan, thanks for that reminder of starting with a digit. Using piping solves the saving issue. But for some reasons, even though the data is effectively saved, the data doesn't seem to be able to be loaded back to R environment. I think this is a separate question, so I've created a new one here stackoverflow.com/questions/62586733/…
0

I ended here trying to avoid my common use of eval(parse(text =...)) and unfortunately, I found that is a good solution for this problem. If 'eval' didn't make it on the original post, it is because the whole expression has to be inside eval, not only the name of the object to be saved:

#### Nedeed original code

res <- 12345
sku = 'sku_a'
index = '1'
assign(paste0(index,'_arima_',sku), res) 
get(paste0(index,'_arima_',sku))

#### Solution to the problem

## save using "eval(parse(text=...))"  
eval(parse(text = paste0("save('",index,"_arima_",sku,
                         "', file = '",index,"_arima_",sku,".RData')")))

## checking
rm(list=ls())
load("1_arima_sku_a.RData")
get("1_arima_sku_a")

Looking forward to hearing a solution to this avoiding 'eval'. In my case, I don't use numbers in the name of the object but still, the name changes on each loop iteration.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.