0

I am trying to create a variable that is a function of 4 other variables. I have the following code:

set.seed(123)
iter <- 1000
group <- c('A','B','C','D','E','F')
for (i in group) {
  df <- df1[df1$group == i,]
  x_ <- vector(mode="numeric", length=1000)
  assign(eval(paste0("X_", i)), globalenv())   #This is the issue

  a <- rnorm(iter, mean=df$a, sd=df$sea)
  b <- rnorm(iter, mean=df$b, sd=df$seb)
  c <- rnorm(iter, mean=df$c, sd=df$sec)
  z <- rnorm(iter, mean=df$zbar, sd=df$se_z)

  X_[i] = (a + c*(z-df$zbar))/(-b)
}

I am unable to create a unique group-specific variable (e.g. X_A, X_B, ...) and I am unsure why the -assign( )- function is not working properly. The dataframe df1 has 6 rows (one for each group) and then the number of columns is equal to the number of variables plus a string variable for group. I am not trying to append this new variables X_[i] to the dataset I am just trying to place it in the global environment. I believe the issue lies in my assigning the placement of the variable, but it isn't generating a numeric variable X.

df1 is a dataframe with 6 observations of 9 variables containing a, sea, b, seb, c, sec, zbar, se_z. These are just the means and standard deviations of a, b, c, and z, respectively. The 9th variable is group which contains A, B, ..., F. When I use the code df <-df1[df1$group == i,] I am trying to create a unique X variable for each group entity.

3
  • Can you precise what is df1 and crop ? and also provide a reproducible example of df1 if df1 is a dataframe Commented Dec 6, 2019 at 20:39
  • I have updated the question, thank you for pointing this out Commented Dec 6, 2019 at 20:44
  • 2
    This is a bad design patter in R. Rather than pasting data in to names of variables, store values in a named list. This makes things much, much easier to work with in R. get()/assign() should generally be avoided Commented Dec 6, 2019 at 20:49

3 Answers 3

2

Try something like this:

dynamicVariableName <- paste0("X_", i)
assign(dynamicVariableName, (a + c*(z-df$zbar))/(-b))
Sign up to request clarification or add additional context in comments.

Comments

1

Alternatively to the answer from @ErrorJordan, you can write your loop like that:

set.seed(123)
iter <- 1000
group <- c('A','B','C','D','E','F')
for(i in group)
{
  df <- df1[df1$group == i,]

  a <- rnorm(iter, mean=df$a, sd=df$sea)
  b <- rnorm(iter, mean=df$b, sd=df$seb)
  c <- rnorm(iter, mean=df$c, sd=df$sec)
  z <- rnorm(iter, mean=df$zbar, sd=df$se_z)

  X <- (a + c*(z-df$zbar))/(-b)
  assign(paste0("X_",i),X,.GlobalEnv)
}

As suggested by @MrFlick, you can also stored your data into a list, to do so you can just modify your loop to get:

set.seed(123)
iter <- 1000
group <- c('A','B','C','D','E','F')  
X = vector("list",length(group))
names(X) = group
for(i in 1:length(group))
{
  df <- df1[df1$group == group[i],]    
  a <- rnorm(iter, mean=df$a, sd=df$sea)
  b <- rnorm(iter, mean=df$b, sd=df$seb)
  c <- rnorm(iter, mean=df$c, sd=df$sec)
  z <- rnorm(iter, mean=df$zbar, sd=df$se_z)

  X[[i]] <- (a + c*(z-df$zbar))/(-b)
}

df1 dataframe

df1 = data.frame(a = c(1:6),
                 b = c(1:6),
                 c = c(1:6),
                 zbar = c(1:6),
                 sea = rep(1,6),
                 seb = rep(1,6),
                 sec = rep(1,6),
                 se_z = rep(1,6),
                 group = group)

Comments

0

It's a little hard to parse what you want to do, but I'm assuming it's something like

for each value in group make an object (in the global env) called X_A, X_B, ...

for each one of those objects, assign it the value (a + c*(z-df$zbar))/(-b)

I think this should do that for you:

set.seed(123)
group <- c('A','B','C','D','E','F')
for (i in group) {
  df <- df1[df1$group == i,]

  a <- rnorm(iter, mean=df$a, sd=df$sea)
  b <- rnorm(iter, mean=df$b, sd=df$seb)
  c <- rnorm(iter, mean=df$c, sd=df$sec)
  z <- rnorm(iter, mean=df$zbar, sd=df$se_z)

  assign(paste0("X_", i), (a + c*(z-df$zbar))/(-b), globalenv())
}

Note that in the code example you gave, the command iter <- 1000 has no effect, and the command x_ <- vector(mode="numeric", length=1000) also has no effect. By that I mean, you make those objects, but never subsequently use them in any further computation. If those commands should do something meaningful I'll need your help in explaining their intended purpose.

1 Comment

Iter is used at the beginning of each random variable generation as the number of observations, the vector one is not used though thanks for pointing that out

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.