如何绘制无替换填充数据集
How to draw without replacement to fill in data set
我正在生成一个数据集,我首先想从离散分布中为每个观察值随机抽取一个数字,然后用这些数字填充 var1
。接下来,我想从每一行的分布中抽取另一个数字,但要注意的是 var1
中用于此观察的数字不再符合抽取条件。我想重复这个比较多的次数。
为了让这更有意义,假设我从以下内容开始:
id
1
2
3
...
999
1000
假设我的分布是["A"、"B"、"C"、"D"、"E"],概率为[.2] , .3, .1, .15, .25].
我想先从这个分布中随机抽取填入var
。假设这样的结果是:
id var1
1 E
2 E
3 C
...
999 B
1000 A
现在 E
不符合抽取观察值 1
和 2
的条件。 C
、B
和 A
分别不符合观察 3
、999
和 1000
的条件。
填完所有栏目后,我们可能会得到这样的结果:
id var1 var2 var3 var4 var5
1 E C B A D
2 E A B D C
3 C B A E D
...
999 B D C A E
1000 A E B C D
我不确定如何在 Stata 中处理这个问题。但是填写 var1
的一种方法是执行以下操作:
gen random1 = runiform()
replace var1 = "A" if random1<.2
replace var1 = "B" if random1>=.2 & random1<.5
etc....
请注意,在创建 var1
后坚持使用(缩放的)概率是可取的,但对我来说不是必需的。
这是一个解决方案,可以从分发版中以 select 的长格式工作。由于值是 selected,它们被标记为完成,下一个 selection 由包含剩余值的组组成。概率在每次通过时都按比例缩放。
version 14
set seed 3241234
* Example generated by -dataex-. To install: ssc install dataex
clear
input byte ip str1 y double p
1 "A" .2
2 "B" .3
3 "C" .1
4 "D" .15
5 "E" .25
end
local nval = _N
* the following should be true
isid y
expand 1000
bysort y: gen id = _n
sort id ip
gen done = 0
forvalues i = 1/`nval' {
// scale probabilities
bysort id done (ip): gen double ptot = sum(p) // this is a running sum
by id done: gen double phigh = sum(p / ptot[_N])
by id done: gen double plow = cond(_n == 1, 0, phigh[_n-1])
// random number in the range of (0,1) for the group
bysort id done (ip): gen double x = runiform()
// pick from the not done group; choose first x to represent group
by id done: gen pick = !done & inrange(x[1], plow, phigh)
// put the picked obs at the end and create the new var
bysort id (pick ip): gen v`i' = y[_N]
// we are done for the obs that was picked
bysort id: replace done = 1 if _n == _N
drop x pick ptot phigh plow
}
bysort id: keep if _n == 1
我正在生成一个数据集,我首先想从离散分布中为每个观察值随机抽取一个数字,然后用这些数字填充 var1
。接下来,我想从每一行的分布中抽取另一个数字,但要注意的是 var1
中用于此观察的数字不再符合抽取条件。我想重复这个比较多的次数。
为了让这更有意义,假设我从以下内容开始:
id
1
2
3
...
999
1000
假设我的分布是["A"、"B"、"C"、"D"、"E"],概率为[.2] , .3, .1, .15, .25].
我想先从这个分布中随机抽取填入var
。假设这样的结果是:
id var1
1 E
2 E
3 C
...
999 B
1000 A
现在 E
不符合抽取观察值 1
和 2
的条件。 C
、B
和 A
分别不符合观察 3
、999
和 1000
的条件。
填完所有栏目后,我们可能会得到这样的结果:
id var1 var2 var3 var4 var5
1 E C B A D
2 E A B D C
3 C B A E D
...
999 B D C A E
1000 A E B C D
我不确定如何在 Stata 中处理这个问题。但是填写 var1
的一种方法是执行以下操作:
gen random1 = runiform()
replace var1 = "A" if random1<.2
replace var1 = "B" if random1>=.2 & random1<.5
etc....
请注意,在创建 var1
后坚持使用(缩放的)概率是可取的,但对我来说不是必需的。
这是一个解决方案,可以从分发版中以 select 的长格式工作。由于值是 selected,它们被标记为完成,下一个 selection 由包含剩余值的组组成。概率在每次通过时都按比例缩放。
version 14
set seed 3241234
* Example generated by -dataex-. To install: ssc install dataex
clear
input byte ip str1 y double p
1 "A" .2
2 "B" .3
3 "C" .1
4 "D" .15
5 "E" .25
end
local nval = _N
* the following should be true
isid y
expand 1000
bysort y: gen id = _n
sort id ip
gen done = 0
forvalues i = 1/`nval' {
// scale probabilities
bysort id done (ip): gen double ptot = sum(p) // this is a running sum
by id done: gen double phigh = sum(p / ptot[_N])
by id done: gen double plow = cond(_n == 1, 0, phigh[_n-1])
// random number in the range of (0,1) for the group
bysort id done (ip): gen double x = runiform()
// pick from the not done group; choose first x to represent group
by id done: gen pick = !done & inrange(x[1], plow, phigh)
// put the picked obs at the end and create the new var
bysort id (pick ip): gen v`i' = y[_N]
// we are done for the obs that was picked
bysort id: replace done = 1 if _n == _N
drop x pick ptot phigh plow
}
bysort id: keep if _n == 1