Loop to generate new variable using old variable name as a part of new name

Is it possible to repeat a procedure for a list of variables and generate new variables that use part of the old variable name? I have tried to do this as I have a set of variables (vnames) and want to generate new variables as attempted below. I have a set of variables called mg_ts_alph, mg_ts_a1, mg_ts_b0, etc and I am trying to generate a set of variables names mg_pv_alph, mg_pv_a1, mg_pv_b0, etc that uses the respective mg_ts value. I would be grateful if you could let me know where I am going wrong.

string vnames = { "alph", "a1", "b0", "b1", "c0", "e0"};

for i(1, rows(vnames), 1);
    mg_pv_$+vnames[i]=2*cdftc(abs(mg_ts_$+vnames[i]),T-k);
endfor;

3 Answers



1



accepted

I will show you how to do what you are trying to do, but let me first try talking you into doing something different. ? There are a few different options, depending upon the dimensions of your data, etc. The first is to create a vector containing all each of the parameters (assuming they are scalar parameters), like this:

string vnames = { "alph", "a1", "b0", "b1", "c0", "e0"};

T = 100;
k = rows(vnames);

//Assign values for 'alph' 'a1', 'b0, etc for this example
mg_ts = { 0.5, 0.8, 1.1, -0.3, 0.1, 0.4 };

mg_pv = 2 * cdftc(abs(mg_ts), T-k);

If you are open to another method and this does not work for you for some reason, I would encourage you to post the problem you have with this solution and see if we can come up with a better alternative. Otherwise, here is the answer to your original question. It requires the use of varput and varget, like this

string vnames = { "alph", "a1", "b0", "b1", "c0", "e0"};

T = 100;
k = rows(vnames);

//Assign values for 'alph' 'a1', 'b0, etc for this example
mg_ts_alph = 0.5;
mg_ts_a1 = 0.8;
mg_ts_b0 = 1.1;
mg_ts_b1 = -0.3;
mg_ts_c0 = 0.1;
mg_ts_e0 = 0.4;

for i(1, rows(vnames), 1);
    call varput( 2 * cdftc(abs(varget("mg_ts_"$+vnames[i])),T-k), "mg_pv_"$+vnames[i]);
endfor;

aptech

1,773


0



Sorry, I realise I didn't explain myself very clearly in my first instance! I have no variables called "alph", "a1", "b0", "b1", "c0", "e0" in my dataset, but instead have a (nx1) vector of parameters for each of these called "alph_", "a1_", "b0_", "b1_", "c0_", "e0_". These are then used in different forms to generate standard errors, mean group estimates etc etc. I noticed that I am often repeating myself six times ( for each different name) so often in my code. I have pasted 2 snippets of my code to illustrate this below - please do let me know if I am not thinking about this in the right way! If you think the second option is best, I am more than happy to implement this. 

Many thanks ?

**first snippet**

for i (1,N,1);
    y_i=depvar[.,i];
    x_i=const~l_h_tn[.,i]~s_tn[.,i]~sl_tn[.,i]~n~vs[.,i];
    betas=inv(x_i'x_i)*x_i'*y_i;
    alph_[i,1]=betas[1,1]; 
    a1_[i,i]=betas[2,1];
    b0_[i,i]=betas[3,1];
    b1_[i,i]=betas[4,1];
    c0_[i,i]=betas[5,1];
    e0_[i,i]=betas[6,1];
    epsil=y_i-x_i*betas;
    s_sq=epsil'epsil/(t-k);
    varcov_beta=s_sq*inv(x_i'x_i);
    se_betas[.,i]=sqrt(diag(varcov_beta));
    all_betas[.,i]=inv(x_i'x_i)*x_i'*y_i;
    all_epsil[.,i]=y_i-x_i*betas;
endfor;

2nd snippet

regs = indexcat(regid', 1); //all areas belonging to region 1
minc(regs);
maxc(regs);
n_star=rows(regs); //no. of areas

//MG
mge_alph=sumc(alph_v[minc(regs):maxc(regs)])/rows(regs);
mge_a1 = sumc(a1_v[minc(regs):maxc(regs)])/rows(regs);
mge_b0 = sumc(b0_v[minc(regs):maxc(regs)])/rows(regs);
mge_b1 = sumc(b1_v[minc(regs):maxc(regs)])/rows(regs);
mge_c0 = sumc(c0_v[minc(regs):maxc(regs)])/rows(regs);
mge_e0 = sumc(e0_v[minc(regs):maxc(regs)])/rows(regs);

 

//Variance
for i (minc(regs),maxc(regs),1);
    mgv_alph =(alph_v[minc(regs):maxc(regs)]-mge_alph')'*(alph_v[minc(regs):maxc(regs)]-mge_alph')/(rows(regs)*(rows(regs)-1));
    mgv_a1 = (a1_v[minc(regs):maxc(regs)]-mge_a1')'*(a1_v[minc(regs):maxc(regs)]-mge_a1')/(rows(regs)*
    (rows(regs)-1));
    mgv_b0 = (b0_v[minc(regs):maxc(regs)]-mge_b0')'*(b0_v[minc(regs):maxc(regs)]-mge_b0')/(rows(regs)*
    (rows(regs)-1));
    mgv_b1 = (b1_v[minc(regs):maxc(regs)]-mge_b1')'*(b1_v[minc(regs):maxc(regs)]-mge_b1')/(rows(regs)*
    (rows(regs)-1));
    mgv_c0 = (c0_v[minc(regs):maxc(regs)]-mge_c0')'*(c0_v[minc(regs):maxc(regs)]-mge_c0')/(rows(regs)*
    (rows(regs)-1));
    mgv_e0 = (e0_v[minc(regs):maxc(regs)]-mge_e0')'*(e0_v[minc(regs):maxc(regs)]-mge_e0')/(rows(regs)*
    (rows(regs)-1));
endfor;

 

//SEs
mg_se_alph= sqrt(mgv_alph);
mg_se_a1 = sqrt(mgv_a1);
mg_se_b0 = sqrt(mgv_b0);
mg_se_b1 = sqrt(mgv_b1);
mg_se_c0 = sqrt(mgv_c0);
mg_se_e0 = sqrt(mgv_e0);



0



I would recommend a couple of changes: 1) I would try to avoid the creation of the individual scalar values and keep these values together in matrices as much as possible. 2) I would make some procedures to remove some of the repetitions.

//Set so there is a simple runnable example
N = 4;
nobs = 10;
depvar = rndn(nobs, N);
const = ones(nobs, 1);
l_h_tn = rndn(nobs, N);
s_tn = rndn(nobs, N);
sl_tn = rndn(nobs, N);
vs = rndn(nobs, N);
t = nobs;
k = N;
all_betas = zeros(n+1,n);
all_epsil = zeros(nobs,n);
se_betas = zeros(n+1,n);

for i (1,N,1);
    y_i=depvar[.,i];
    //I removed 'n' below, because I think it might be a bug,
    //since it is the length of the 'for' loop counter
    x_i=const~l_h_tn[.,i]~s_tn[.,i]~sl_tn[.,i]~vs[.,i];
    mm = x_i'x_i;

    betas = inv(mm)*x_i'*y_i;
    all_betas[.,i] = betas;

    epsil = y_i-x_i*betas;
    all_epsil[.,i]= epsil;

    s_sq=epsil'epsil/(t-k);
    varcov_beta=s_sq*inv(mm);

    se_betas[.,i]=sqrt(diag(varcov_beta));
endfor;

And then if alph_v, a1_v1, b0_v, etc are all left in matrix form, we can change this

regs = indexcat(regid', 1); //all areas belonging to region 1
minc(regs);
maxc(regs);
n_star=rows(regs); //no. of areas

mge_alph=sumc(alph_v[minc(regs):maxc(regs)])/rows(regs);
mge_a1 = sumc(a1_v[minc(regs):maxc(regs)])/rows(regs);
mge_b0 = sumc(b0_v[minc(regs):maxc(regs)])/rows(regs);
mge_b1 = sumc(b1_v[minc(regs):maxc(regs)])/rows(regs);
mge_c0 = sumc(c0_v[minc(regs):maxc(regs)])/rows(regs);
mge_e0 = sumc(e0_v[minc(regs):maxc(regs)])/rows(regs);

to this

mge = meanc(selif(all_betas, regid' .== 1));

Since I do not have access to any data to run and there appeared to be a possible bug with the n, I cannot promise that there are not any bugs in the code, I posted. However, I think the principal is solid and I am happy to answer any questions you have about it.

aptech

1,773

Your Answer

3 Answers

1
accepted

I will show you how to do what you are trying to do, but let me first try talking you into doing something different. ? There are a few different options, depending upon the dimensions of your data, etc. The first is to create a vector containing all each of the parameters (assuming they are scalar parameters), like this:

string vnames = { "alph", "a1", "b0", "b1", "c0", "e0"};

T = 100;
k = rows(vnames);

//Assign values for 'alph' 'a1', 'b0, etc for this example
mg_ts = { 0.5, 0.8, 1.1, -0.3, 0.1, 0.4 };

mg_pv = 2 * cdftc(abs(mg_ts), T-k);

If you are open to another method and this does not work for you for some reason, I would encourage you to post the problem you have with this solution and see if we can come up with a better alternative. Otherwise, here is the answer to your original question. It requires the use of varput and varget, like this

string vnames = { "alph", "a1", "b0", "b1", "c0", "e0"};

T = 100;
k = rows(vnames);

//Assign values for 'alph' 'a1', 'b0, etc for this example
mg_ts_alph = 0.5;
mg_ts_a1 = 0.8;
mg_ts_b0 = 1.1;
mg_ts_b1 = -0.3;
mg_ts_c0 = 0.1;
mg_ts_e0 = 0.4;

for i(1, rows(vnames), 1);
    call varput( 2 * cdftc(abs(varget("mg_ts_"$+vnames[i])),T-k), "mg_pv_"$+vnames[i]);
endfor;

0

Sorry, I realise I didn't explain myself very clearly in my first instance! I have no variables called "alph", "a1", "b0", "b1", "c0", "e0" in my dataset, but instead have a (nx1) vector of parameters for each of these called "alph_", "a1_", "b0_", "b1_", "c0_", "e0_". These are then used in different forms to generate standard errors, mean group estimates etc etc. I noticed that I am often repeating myself six times ( for each different name) so often in my code. I have pasted 2 snippets of my code to illustrate this below - please do let me know if I am not thinking about this in the right way! If you think the second option is best, I am more than happy to implement this. 

Many thanks ?

**first snippet**

for i (1,N,1);
    y_i=depvar[.,i];
    x_i=const~l_h_tn[.,i]~s_tn[.,i]~sl_tn[.,i]~n~vs[.,i];
    betas=inv(x_i'x_i)*x_i'*y_i;
    alph_[i,1]=betas[1,1]; 
    a1_[i,i]=betas[2,1];
    b0_[i,i]=betas[3,1];
    b1_[i,i]=betas[4,1];
    c0_[i,i]=betas[5,1];
    e0_[i,i]=betas[6,1];
    epsil=y_i-x_i*betas;
    s_sq=epsil'epsil/(t-k);
    varcov_beta=s_sq*inv(x_i'x_i);
    se_betas[.,i]=sqrt(diag(varcov_beta));
    all_betas[.,i]=inv(x_i'x_i)*x_i'*y_i;
    all_epsil[.,i]=y_i-x_i*betas;
endfor;

2nd snippet

regs = indexcat(regid', 1); //all areas belonging to region 1
minc(regs);
maxc(regs);
n_star=rows(regs); //no. of areas

//MG
mge_alph=sumc(alph_v[minc(regs):maxc(regs)])/rows(regs);
mge_a1 = sumc(a1_v[minc(regs):maxc(regs)])/rows(regs);
mge_b0 = sumc(b0_v[minc(regs):maxc(regs)])/rows(regs);
mge_b1 = sumc(b1_v[minc(regs):maxc(regs)])/rows(regs);
mge_c0 = sumc(c0_v[minc(regs):maxc(regs)])/rows(regs);
mge_e0 = sumc(e0_v[minc(regs):maxc(regs)])/rows(regs);

 

//Variance
for i (minc(regs),maxc(regs),1);
    mgv_alph =(alph_v[minc(regs):maxc(regs)]-mge_alph')'*(alph_v[minc(regs):maxc(regs)]-mge_alph')/(rows(regs)*(rows(regs)-1));
    mgv_a1 = (a1_v[minc(regs):maxc(regs)]-mge_a1')'*(a1_v[minc(regs):maxc(regs)]-mge_a1')/(rows(regs)*
    (rows(regs)-1));
    mgv_b0 = (b0_v[minc(regs):maxc(regs)]-mge_b0')'*(b0_v[minc(regs):maxc(regs)]-mge_b0')/(rows(regs)*
    (rows(regs)-1));
    mgv_b1 = (b1_v[minc(regs):maxc(regs)]-mge_b1')'*(b1_v[minc(regs):maxc(regs)]-mge_b1')/(rows(regs)*
    (rows(regs)-1));
    mgv_c0 = (c0_v[minc(regs):maxc(regs)]-mge_c0')'*(c0_v[minc(regs):maxc(regs)]-mge_c0')/(rows(regs)*
    (rows(regs)-1));
    mgv_e0 = (e0_v[minc(regs):maxc(regs)]-mge_e0')'*(e0_v[minc(regs):maxc(regs)]-mge_e0')/(rows(regs)*
    (rows(regs)-1));
endfor;

 

//SEs
mg_se_alph= sqrt(mgv_alph);
mg_se_a1 = sqrt(mgv_a1);
mg_se_b0 = sqrt(mgv_b0);
mg_se_b1 = sqrt(mgv_b1);
mg_se_c0 = sqrt(mgv_c0);
mg_se_e0 = sqrt(mgv_e0);

0

I would recommend a couple of changes: 1) I would try to avoid the creation of the individual scalar values and keep these values together in matrices as much as possible. 2) I would make some procedures to remove some of the repetitions.

//Set so there is a simple runnable example
N = 4;
nobs = 10;
depvar = rndn(nobs, N);
const = ones(nobs, 1);
l_h_tn = rndn(nobs, N);
s_tn = rndn(nobs, N);
sl_tn = rndn(nobs, N);
vs = rndn(nobs, N);
t = nobs;
k = N;
all_betas = zeros(n+1,n);
all_epsil = zeros(nobs,n);
se_betas = zeros(n+1,n);

for i (1,N,1);
    y_i=depvar[.,i];
    //I removed 'n' below, because I think it might be a bug,
    //since it is the length of the 'for' loop counter
    x_i=const~l_h_tn[.,i]~s_tn[.,i]~sl_tn[.,i]~vs[.,i];
    mm = x_i'x_i;

    betas = inv(mm)*x_i'*y_i;
    all_betas[.,i] = betas;

    epsil = y_i-x_i*betas;
    all_epsil[.,i]= epsil;

    s_sq=epsil'epsil/(t-k);
    varcov_beta=s_sq*inv(mm);

    se_betas[.,i]=sqrt(diag(varcov_beta));
endfor;

And then if alph_v, a1_v1, b0_v, etc are all left in matrix form, we can change this

regs = indexcat(regid', 1); //all areas belonging to region 1
minc(regs);
maxc(regs);
n_star=rows(regs); //no. of areas

mge_alph=sumc(alph_v[minc(regs):maxc(regs)])/rows(regs);
mge_a1 = sumc(a1_v[minc(regs):maxc(regs)])/rows(regs);
mge_b0 = sumc(b0_v[minc(regs):maxc(regs)])/rows(regs);
mge_b1 = sumc(b1_v[minc(regs):maxc(regs)])/rows(regs);
mge_c0 = sumc(c0_v[minc(regs):maxc(regs)])/rows(regs);
mge_e0 = sumc(e0_v[minc(regs):maxc(regs)])/rows(regs);

to this

mge = meanc(selif(all_betas, regid' .== 1));

Since I do not have access to any data to run and there appeared to be a possible bug with the n, I cannot promise that there are not any bugs in the code, I posted. However, I think the principal is solid and I am happy to answer any questions you have about it.


You must login to post answers.

Have a Specific Question?

Get a real answer from a real person

Need Support?

Get help from our friendly experts.