[R] reference generated var name in loop

Evan Cooch ev@n@cooch @end|ng |rom gm@||@com
Sun May 28 18:28:14 CEST 2023


Thanks very much - that does the trick. Many good suggestions.

On 5/26/2023 12:00 PM, Greg Snow wrote:
> Using the `assign` function is almost always a sign that you are
> making things more complicated than is needed.  It is better to work
> directly with lists, which make it much easier to set and get names.
>
> Your code and description can be done pretty simply using the `lapply
> function (often easier than using a loop if the desire is to save the
> output of each iteration), here is one example:
>
> parms <- c(a=4, b=6, c=11)
>
> tmp1 <- lapply(parms, function(mu){
>    rnorm(5, mu, 0.25)
> })
>
> names(tmp1) <- paste0(names(parms), "_r")
> ranvec <- as.data.frame(tmp1)
> ranvec
>
> We can skip the temporary variable(s) by using pipes like this:
>
> parms |>
>    lapply( rnorm, n=5, sd=0.25 ) |>
>    setNames( paste0(names(parms), "_r")) |>
>    as.data.frame()
>
> Your line using `sub` does not do anything.  While the `=` sign was
> used to create the vector with names, the vector itself does not
> contain any `=` signs and so there is no reason to try to remove
> anything.  The `parms` vector already contains the numbers that you
> are trying to extract (plus a names attribute which will be ignored
> when not needed, so usually there is no reason to remove the names).
>
> The `lapply` function runs the function passed in (an anonymous
> function in the first example, the `rnorm` function in the second) on
> each element of the vector/list passed in as the first argument and
> stores each result as an element in a list, which is then returned
> (and in my examples named then converted to a data frame).
>
> The `sapply` function would combine the resulting vectors into a
> matrix, and would handle the naming automatically, so something as
> simple as:
>
> sapply(parms, rnorm, n=5, sd=0.25)
>
> may do what you want (you could pipe that to `as.data.frame` if you
> really need a data frame).
>
>
> The purrr package (part of the tidyverse) gives some additional
> functions similar to `lapply` and `sapply` but with extra bells and
> whistles.
>
> If you really want to use a loop, then take advantage of the fact that
> the data frame is a special case of a list and try something like:
>
> ranvec <- data.frame(row.names=1:5)
> for(i in seq_along(parms)) {
>    tmp.nm <- paste0(names(parms)[i], '_r')
>    ranvec[[tmp.nm]] <- rnorm(5, parms[i], 0.25)
> }
>
> or
>
> ranvec <- data.frame(row.names=1:5)
> for(nm in names(parms)) {
>    tmp.nm <- paste0(nm, '_r')
>    ranvec[[tmp.nm]] <- rnorm(5, parms[nm], 0.25)
> }
>
>
> On Fri, May 26, 2023 at 8:50 AM Evan Cooch <evan.cooch using gmail.com> wrote:
>> Greetings --
>>
>> I'm trying to write some code that basically does the following:
>>
>> 1\ user inputs a list of parameter names, and parameter values.
>>
>> 2\ code parses this list, extracting parameter names and values separately
>>
>> 3\ loops over the number of parameters, and for each parameter,
>> generates something (say, rnorm) based on the value corresponding to
>> that parameter.
>>
>> 4\ assigns a new name to the vector of rnorm data, where the name is a
>> permutation of the original parameter name. In the example (below) I
>> simply past "_r" to the original parameter name (to indicate, say, its
>> some rnorm values associated that that variable).
>>
>> 5\the 'I'm stumped' part -- output the newly named vector into something
>> (say, data.frame), which requires being able to reference the newly
>> named vector, which is what can't figure out how to accomplish.
>>
>> Here is a MWE of sorts -- the starting list of parameter names and
>> values is in a list I call parms.
>>
>>    parms <- c(a=4,b=6,c=11) # list of parms user could pass to a function
>>
>>    nvars <- names(parms)  # extract parameter names
>>
>>    vals <- sub("\\=.*", "", parms) # extract parameter values
>>
>>    n <- length(parms) # determine number of parameters
>>
>>    ranvec <- data.frame() # to store stuff from loop
>>
>>    for (i in 1:n) {
>>      pn <- nvars[i]; # get name of parm variable
>>      rn <- rnorm(5,as.numeric(vals[i]),0.25) # generate rnorm based on
>> parm value
>>      assign(paste(pn, "_r", sep=""),rn) # creates a_r, b_r, c_r...
>>      ** here is where I want to output to ranvec, but I can't see how to
>> do it since the loop doesn't know the name of the new var created in
>> preceding step...**
>>    }
>>
>>
>> In the end, I want to create a data frame containing rnorm deviates for
>> each of a set of user-specified variables, which I can reference in some
>> fashion using a permuted version of the original variable name.
>>
>> Suggestions?
>>
>> Many thanks...
>>
>> ______________________________________________
>> R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>
>



More information about the R-help mailing list