Search code examples
rloopsassigndynamic-variables

Alternative to assign function in r


I am using the following code in a loop, I am just replicating the part which I am facing the problem in. The entire code is extremely long and I have removed parts which are running fine in between these lines. This is just to explain the problem:

    for (j in 1:2)
     {
      assign(paste("numeric_data",j,sep="_"),unique_id)
      for (i in 1:2)
      {
       assign(paste("numeric_data",j,sep="_"), 
              merge(eval(as.symbol(paste("numeric_data",j,sep="_"))),
              eval(as.symbol(paste("sd_1",i,sep="_"))),all.x = TRUE))
       }
      }

The problem that I am facing is that instead of assign in the second step, I want to use (eval+paste)

    for (j in 1:2)
     {
      assign(paste("numeric_data",j,sep="_"),unique_id)
      for (i in 1:2)
      {
       eval(as.symbol((paste("numeric_data",j,sep="_"))))<- 
              merge(eval(as.symbol(paste("numeric_data",j,sep="_"))),
              eval(as.symbol(paste("sd_1",i,sep="_"))),all.x = TRUE)
       }
      }

However R does not accept eval while assigning new variables. I looked at the forum and everywhere assign is suggested to solve the problem. However, if I use assign the loop overwrites my previously generated "numeric_data" instead of adding to it, hence I get output for only one value of i instead of both.


Solution

  • Here is a very basic intro to one of the most fundamental data structures in R. I highly recommend reading more about them in standard documentation sources.

    #A list is a (possible named) set of objects
    numeric_data <- list(A1 = 1, A2 = 2)
    #I can refer to elements by name or by position, e.g. numeric_data[[1]]
    > numeric_data[["A1"]]
    [1] 1
    
    #I can add elements to a list with a particular name 
    > numeric_data <- list()
    > numeric_data[["A1"]] <- 1
    > numeric_data[["A2"]] <- 2
    > numeric_data
    $A1
    [1] 1
    
    $A2
    [1] 2
    
    #I can refer to named elements by building the name with paste() 
    > numeric_data[[paste0("A",1)]]
    [1] 1
    
    #I can change all the names at once... 
    > numeric_data <- setNames(numeric_data,paste0("B",1:2))
    > numeric_data
    $B1
    [1] 1
    
    $B2
    [1] 2
    
    #...in multiple ways 
    > names(numeric_data) <- paste0("C",1:2)
    > numeric_data
    $C1
    [1] 1
    
    $C2
    [1] 2
    

    Basically, the lesson is that if you have objects with names with numeric suffixes: object_1, object_2, etc. they should almost always be elements in a single list with names that you can easily construct and refer to.