我想从总分中模拟项目得分。
例如,我生成了总分,总分在25
和5
之间。我想将此总分分配给五个项目,每个项目的得分为while
-Likert。
然后,我使用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
}
}
循环来检查Stata 15中的条件。代码花费了太长时间才能完成循环,并且我不知道自己是否犯了错误。
也许有人想提出另一种从总分中模拟项目得分的方法吗?
我的代码:
2
我想要的预期数据:
如您所见,运行循环后,我总是会遇到4
-item1
的情况,程序会通过生成项目得分(item5
-diff
来继续运行直到var sortedSelectedRows = myGridControl.SelectedRows
.Cast<DataGridViewRow>()
.Select(x=> x.DataBoundItem)
.Cast<ItemModelClass>()
.OrderBy(x => x.TimeStamp)
.ToList();
变量等于零为止。
答案 0 :(得分:0)
如果我理解正确,则可以循环以下内容(将所有项目设置为初始值1后,因为可能的值是1到5):
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
换句话说,如果sum_item < y
,则将1随机添加到其中一个项目中(只要该项目尚未等于5),然后您将继续进行直到{{ 1}}。
因此,如果sum_item == y
的最大值为25,并且项从1到5,则将在大约20个迭代中收敛。我之所以说“大致”是因为在这里加1到一个已经等于5的项目。您可以为此添加一些额外的代码,但是如果这样做足够快,我就不会打扰。例如。对于高y
的值,从初始值5开始并随机减去1直至收敛,会更有效。
我还不足以说统计学是做到这一点的最佳方法,甚至是一种适当的方法,但从直觉上来说,如果您想要一个相当均匀的价值分布,这似乎还可以。例如,如果您希望将模态值设为4,则难度会大得多,并且不再是真正的编程问题。