使用foreach生成新变量作为现有函数

时间:2018-04-19 11:32:37

标签: loops stata

我搜索了论坛,但遗憾的是找不到我的问题的解决方案。我为30名研究参与者提供了400次重复测量,我希望为每个参与者生成测量对之间的差异。所以我认为foreach命令会为我节省很多工作。

变量名称有一个前缀,可以将第一次和第二次测量分开:S_meE_me。接下来是22个字符长的特定代码,允许我选择正确的措施:

所以我想要一个新变量= S_me_XXXXXXXXXXXXXXXXXXXXX1E_me_XXXXXXXXXXXXXXXXXXXXX1之间的差异,S_me_XXXXXXXXXXXXXXXXXXXXX2E_me_XXXXXXXXXXXXXXXXXXXXX2之间差异的1个新变量,最多S_me_XXXXXXXXXXXXXXXXXXX400E_me_XXXXXXXXXXXXXXXXXXX400

我现在尝试过:

unab where : S_me*
local where " `where'" 
local where : subinstr local where " S_me" " ", all 
display "`where'" 

foreach c of local where {
    gen Diff_`c' = S_me`c'- E_me`c' 
} 

因为我在这里找到了类似的帖子 - 但它不起作用。

也不是:

foreach x of varlist S_me* {
    gen Diff_`x' = (S_me`x'-E_me`x')
} 

现在我希望有人能够找到解决问题的好方法。

3 个答案:

答案 0 :(得分:1)

这会捕获所有S_me*个变量,并在此变量与以E开头的相应变量之间生成400个差异。

qui ds S_me_*
local x = 1
foreach v in `r(varlist)' {
    local str = substr("`v'",2,.)
    gen diff_`x' = `v' - E`str'
    local x = `x' + 1
}

编辑更简单

local x = 1
foreach v of var S_me_*  {
    local str = substr("`v'",2,.)
    gen diff_`x' = `v' - E`str'
    local x = `x' + 1
}

答案 1 :(得分:1)

reshape的要点可以用精简版本来说明。你显然有像

这样的东西
clear 
input id S_me_X1 E_me_X1 S_me_X2 E_me_X2 
1    3 4 5 7    
2    10 12 14 16 
end 

- 只是不同的变量名称和值以及变量和值的数量。

一旦reshape差异只是一个新变量:

reshape long S_me_ E_me_ , i(id) j(which) string 

gen diff = S_me - E_me 

list


     +-----------------------------------+
     | id   which   S_me_   E_me_   diff |
     |-----------------------------------|
  1. |  1      X1       3       4     -1 |
  2. |  1      X2       5       7     -2 |
  3. |  2      X1      10      12     -2 |
  4. |  2      X2      14      16     -2 |
     +-----------------------------------+

一旦你进入每次做某事时创造400个新变量的情况,你就会陷入困境。您将如何描述,绘制或建模它们?

答案 2 :(得分:1)

我认为尼克的答案是迄今为止最简单的答案,你可以reshape之后再回到wide来了解我在这里所做的事情,但我将展示另一种方法来做到这一点。如果您正在使用具有基线的调查数据,因为这似乎就是您正在做的事情,并且使用时间序列运算符可能在此处有价值,具体取决于您对此数据执行的其他操作。从技术上讲,这不是孤立的这个问题的最佳解决方案。注意:为简单起见,我使用4个变量而不是400来执行此操作:

数据输入:

* First, input data

clear
set obs 30
gen id = _n // Id for each participant
forvalues i = 1/4 {
    local first = "S_me_" + string(`i')
    gen `first' = runiform()
    local second = "E_me_" + string(`i')
    gen `second' = rnormal()
}

现在,您基本上将拥有一个“预”期间数据集和一个“发布”期间数据集,我们将在另一个数据集之上添加一个:

* Now, save E dataset separately, and append to bottom of S
preserve
    keep id E*
    * rename variables to common name
    forvalues i = 1/4 {
        rename E_me_`i' me`i'
    }
    tempfile E
    save `E'
restore

drop E*
* Rename variables to common name
forvalues i = 1/4 {
        rename S_me_`i' me`i'
    }

append using `E', gen(period)

* Set time series
tsset id period

* Generate first difference variable using ts operator "d."
foreach x of varlist me* {
    gen `x'_diff = d.`x'
}