0

How does one use the string coming from a loop - to generate new variables
- as a part of functions commands
- as functions' arguments
- as a part of if statements
in R?

Specifically, as an example (the code obviously doesn't work, but I'd like to have something not less intelligible than what is bellow),

list_dist <- c("unif","norm")
for (dist in list_dist){
    paste("rv",dist,sep="") = paste("r",dist,sep="")(100,0,1)
    paste("meanrv",dist,sep="") = mean(paste("rv",dist,sep=""))
    if (round(paste("meanrv",dist,sep=""),3) != 0){
        print("Not small enough")
    }
}

Note: This is an example and I do need to use kind of loops to avoid writing huge scripts.


I managed to use strings as in the example above but only with eval/parse/text/paste and combining the whole statement (i.e. the whole "line") inside paste, instead of pasting only in the varname part or the function part, which makes code ugly and illegible and coding inefficient.

Other available replies to similar questions which I've seen are not specific as in how to deal with this sort of usage of strings from loops.

I'm sure there must be a more efficient and flexible way to deal with this, as there is in some other languages.

Thanks in advance!

5
  • 2
    Put these into a list: myList <- list(); for...; myList[[paste("rv",dist,sep="")]] <- paste("r",dist,sep="")(100,0,1) and so on. Commented Sep 13, 2016 at 12:15
  • 1
    Or use assign() and get() Commented Sep 13, 2016 at 12:19
  • 1
    Also do.call. Commented Sep 13, 2016 at 12:20
  • 2
    At the end of the day, give more insight on what you're trying to do, you're probably taking the problem from the wrong side. Also known as a XY problem Commented Sep 13, 2016 at 12:21
  • Thank you for the suggestions! I also tried do.call but got stuck when I wanted to create a new var with the string from the loop as a part of the name and using the do.call results (which in turn uses the loop). Anyhow, thank you Commented Sep 13, 2016 at 13:16

2 Answers 2

3

Resist the temptation of creating variable names programmatically. Instead, structure your data properly into lists:

list_dist = list(unif = runif, norm = rnorm)
distributions = lapply(list_dist, function (f) f(100, 0, 1))
means = unlist(lapply(distributions, mean))
# … etc.

As you can see, this also gets rid of the loop, by using list functions instead.

Your last step can also be vectorised:

if (any(round(means, 3) != 0))
    warning('not small enough')
Sign up to request clarification or add additional context in comments.

1 Comment

I was curious to see whether and how it was possible to give an answer to this specific way of coding. In any case, you are right, I can do this in several ways and your suggestion is very interesting (note: just starting to learn R, so I do appreciate the a lot these suggestions). Thank you!
0

try this:

list_dist <- list(unif = runif,norm = rnorm)
for (i in 1:length(list_dist)){
    assign(paste("rv",names(list_dist)[i],sep=""), list_dist[[i]](100,0,1))
    assign(paste("meanrv",names(list_dist)[i],sep=""),mean(get(paste("rv",names(list_dist)[i],sep=""))))
    if (round(get(paste("meanrv",names(list_dist)[i],sep="")),3) != 0){
        print("Not small enough")
    }
}

2 Comments

It’s almost certainly better to assign the results in to a named list rather than into the current environment. It definitely simplifies the code.
I tried to give the answer as close as i could to the original request. you are probably right though

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.