Search code examples
rreferencepass-by-reference

Perform same operation to multiple variables, assigning result


I'm working on a project where I have to apply the same transformation to multiple variables. For example

a <- a + 1
b <- b + 1
d <- d + 1
e <- e + 1

I can obviously perform the operations in sequence using

for (i in c(a, b, d, e)) i <- i + 1

However, I can't actually assign the result to each variable this way, since i is a copy of each variable, not a reference.

Is there a way to do this? Obviously, it'd be easier if the variables were merged in a data.frame or something, but that's not possible.


Solution

  • The question states that the variables to increment cannot be in a larger structure but then in the comments it is stated that that is not so after all so we will assume they are in a list L.

    L <- list(a = 1, b = 2, d = 3, e = 4) # test data
    
    for(nm in names(L)) L[[nm]] <- L[[nm]] + 1
    
    # or
    L <- lapply(L, `+`, 1)
    
    # or
    L <- lapply(L, function(x) x + 1)
    

    Scalars

    If they are all scalars then they can be put in an ordinary vector:

    v <- c(a = 1, b = 2, d = 3, e = 4)
    v <- v + 1
    

    Vectors

    If they are all vectors of the same length they can be put in data frame or if they are also of the same type they can be put in a matrix in which case we can also add 1 to it.

    Environment

    If the variables do have to be free in an environment then if nms is a vector of the variable names then we can iterate over the names and use those names to subscript the environment env. If the names follow some pattern we may be able to use nms <- ls(pattern = "...", envir = env) or if they are the only variables in that environment we can use nms <- ls(env).

    a <- b <- d <- e <- 1 # test data
    
    env <- .GlobalEnv  # can change this if not being done in global envir
    nms <- c("a", "b", "d", "e")
    
    for(nm in nms) env[[nm]] <- env[[nm]] + 1
    
    a;b;d;e  # check
    ## [1] 2
    ## [1] 2
    ## [1] 2
    ## [1] 2