Stata 如何从总分变量生成项目变量

Stata 如何从总分变量生成项目变量,stata,Stata,我想从总分中模拟项目分数 例如,我已经生成了总分,总分介于5和25之间。我想将总分分配给五个项目,每个项目都有5-Likert分数 然后我使用while循环检查Stata 15中的条件。代码花了太长时间来完成循环,我不知道我是否犯了错误 也许有人想建议另一种方法来模拟总分中的项目分数 我的代码: set obs 200 generate id=_n generate u_i= rnormal(0, 0.5) generate gr = runiform()>0.5 generate se

我想从总分中模拟项目分数

例如,我已经生成了总分,总分介于
5
25
之间。我想将总分分配给五个项目,每个项目都有
5
-Likert分数

然后我使用
while
循环检查Stata 15中的条件。代码花了太长时间来完成循环,我不知道我是否犯了错误

也许有人想建议另一种方法来模拟总分中的项目分数

我的代码:

set obs 200

generate id=_n
generate u_i= rnormal(0, 0.5)
generate gr = runiform()>0.5
generate sex = runiform()>0.4
generate age = round(rnormal(65, 10))

expand 5

bysort id: generate time=_n  

generate e_ij = rnormal(0, 1.0)

generate run=_n

*Generate Sum score 5-25

generate y = 3.0 + 2.0*gr + 0.2*age -1.2*sex + 0.5*time + u_i + e_ij

summarize y

replace y = round(y)

*Generate each item

forvalues k = 1(1)5 {
    generate item`k' = runiform(1, 5)
    replace item`k' = round(item`k')
}

egen sum_item=rowtotal(item1 item2 item3 item4 item5)       
generate diff = y - sum_item


*Looping check if y=sum_item    

forvalues a = 1(1)`=_N'  {
    quietly gsort -diff
    while sum_item!=y[`a'] {
        replace sum_item=. if sum_item!=y[_n]

        forvalues k = 1(1)5 {   
           replace item`k' =. if sum_item==.

           replace item`k' = runiform(1, 5) if item`k'==.
           replace item`k' = round(item`k') 
                        }
           replace sum_item= item1 + item2+item3+item4+item5 if sum_item==.
           replace diff = y - sum_item  
           if (sum_item==y[`a']) continue, break
        }
    }
我希望得到的预期数据:


如您所见,在运行循环后,我将始终获得程序通过生成项目分数(
item1
-
item5
)来保持运行的
2
-
4
案例,直到
diff
变量等于零。

如果我理解正确,您可以像下面这样循环(将所有项目设置为初始值1后,因为可能的值为1到5):

捕获生成rand\u int=0
替换rand_int=floor(5*runiform()+1)//随机int,1到5
捕获生成cnd=0
对于值k=1(1)5{
替换cnd=rand\u int=`k'和sum\u item
换句话说,也就是说,如果
sum\u item
,则随机向其中一个项添加1(只要该项不等于5),然后继续执行该操作,直到所有行的
sum\u item==y

如果
y
的最大值是25,项目从1到5,那么这将在大约20次迭代中收敛因为当你给一个已经等于5的项目加1时,这里有一点浪费。你可以为此添加一些额外的代码,但我不想麻烦这是否足够快。例如,对于
item\u sum
的高值,从初始值5开始,随机减去1,直到收敛,这样会更有效


作为一名统计学家,我还不足以说这是最好的,甚至是一种适当的方法,但直觉上,如果你想要一个相当均匀的值分布,这似乎是可以的。例如,如果你想要模态值为4,这将非常困难,不再是一个真正的编程问题。

如果我理解正确,你可以d循环如下(将所有项目设置为初始值1后,因为可能的值为1到5):

捕获生成rand\u int=0
替换rand_int=floor(5*runiform()+1)//随机int,1到5
捕获生成cnd=0
对于值k=1(1)5{
替换cnd=rand\u int=`k'和sum\u item
换句话说,也就是说,如果
sum\u item
,则随机向其中一个项添加1(只要该项不等于5),然后继续执行该操作,直到所有行的
sum\u item==y

如果
y
的最大值是25,项目从1到5,那么这将在大约20次迭代中收敛因为当你给一个已经等于5的项目加1时,这里有一点浪费。你可以为此添加一些额外的代码,但我不想麻烦这是否足够快。例如,对于
item\u sum
的高值,从初始值5开始,随机减去1,直到收敛,这样会更有效

作为一名统计学家,我不足以说这是最好的,甚至是一种适当的方法,但直觉上,如果你想要一个相当均匀的值分布,这似乎是可以的。例如,如果你想要模态值为4,这将非常困难,不再是一个真正的编程问题

capture generate rand_int = 0
replace rand_int = floor( 5 * runiform() + 1 )  // random int, 1 to 5
capture generate cnd = 0

forvalues k = 1(1)5 {
    replace cnd = rand_int == `k' & sum_item < y & item`k' < 6
    replace item`k' = item`k' + 1 if cnd
}

replace sum_item = item1+item2+item3+item4+item5