使用大数据集生成样本
Generate samples with big dataset
我有一个大数据集,正因为它很大,所以我必须拆分它或一次加载一个变量。我已经加载了唯一标识符 id,我需要 select 随机 50 次观察 100 次。我搜索了一下,找到了 sample 和 runiform 来生成随机样本,但是我的问题是我需要生成 100 个样本,每个样本有 50 个观察值,因为我需要从整个数据集中采样,这个数据集很大,我只能保留一个变量内存,所以我需要将采样结果保存 100 次。我知道我可以使用 for 循环,但它效率不高,甚至 10 个循环也需要很多时间,有没有更快的方法来生成多个样本?
这是我的代码:
scalar i=0
forvalues i=1(1)100{
clear all
use generated/data1.dta
sample 50,count
save generated/sample`i'.dta,replace
merge 1:m id using generated/10m.dta
keep if _merge==3 |_merge==1
drop _merge
compress
save generated/sample`i'.dta,replace
}
我的原始文件是面板数据,我把原始文件分成几块以便处理,现在我需要 select 100 个随机样本,在代码中我用 for 循环做到了但是我认为这不是有效的方法。
为了更好地描述这个问题,我有一个每天观察价格、return、日期股息等的公司数据集,问题是原始文件非常大,因此要将它加载到内存中,我不得不将它拆分6 件,以便 Stata 可以加载它。现在我需要 select 100 个样本,每个样本有 50 个公司,我正在用这个周期来做:
***Generate 100 samples***
scalar i=0
forvalues i=1(1)100{
clear all
***Select 50 companies at random***
use generated/ids.dta
sample 50,count
***Merge with part1 of the original file***
merge 1:m permno using generated/ids10m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
***Keep in the both file all the ids***
save generated/both`i'.dta,replace
drop if date==.
***Fill the sample`i' with ids which have a correspondence with the date***
save generated/sample`i'.dta,replace
clear all
***Open the both file and keep only the non-match ids***
use generated/both`i'.dta,replace
keep if date==.
keep id
***Keep the non-matched ids to check at the end what's in there***
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id20m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
clear all
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id30m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id40m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id50m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id60m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
erase generated/both`i'.dta
erase generated/rplc`i'.dta
}
现在,这段代码的问题是创建 100 个样本大约需要 40 分钟,有没有更快的方法来做同样的事情?
这是一个事件研究,大小在这里不是问题,问题不在于采样而是循环的效率。
您的 do 文件中有一个地方需要改进:您正在对 600 次采样 ID 与 "big" 文件进行合并。这里的代码只需要对每个大文件进行一次合并,或者在您的情况下需要六个。诀窍是将样本数据从长格式重塑为宽格式,每个 id 一行,并为选择该 id 的样本提供指示符。将此文件与每个大数据集合并后,re-assemble 个样本。玩具示例有两个大文件和三个示例。
clear
/* Generate 1st BIG data set */
input id t
10 1
10 2
40 1
40 2
40 3
50 1
50 2
55 2
55 6
90 2
90 3
end
save big1, replace
* Generate 2nd BIG data set */
clear
input id t
90 4
90 5
100 1
100 2
100 3
140 1
140 2
143 2
155 1
155 2
180 2
180 3
end
save big2, replace
/* Generate three sample data sets-you'll do this with "sample" */
clear
input sample id
1 40
1 180
end
tempfile samp1
save `samp1'
clear
input sample id
2 10
2 90
end
tempfile samp2
save `samp2'
clear
input sample id
3 100
3 155
end
/* Step 1. Append all samples */
append using `samp1' `samp2'
order id sample
sort id sample
list
/* Step 2. Reshape Wide with one obs per id */
tempvar set
gen `set' = sample
reshape wide sample, i(id) j(`set')
tempfile t2
save `t2'
list
/* Step 3. Merge sample ids with each "big" data set
and append the results */
clear
tempfile t3
save `t3', emptyok replace
forvalues g = 1/2 {
use big`g', clear
merge m:1 id using `t2'
keep if _merge ==3
drop _merge
append using `t3'
save `t3', replace
}
sort id t
list, sepby(id)
/* Step 4: Reassemble samples with data into
one data set, saved in advance */
clear
/*temporary file to hold results */
tempfile allsamps
save `allsamps', emptyok
/* Cycle through samples: change 3 to n. of samples */
forvalues i = 1/3 {
use `t3', clear
gen sample = `i' if sample`i'==`i'
drop if sample==.
append using `allsamps'
save `allsamps', replace
}
drop sample?
order sample id
sort sample id t
save allsamples,replace
list, sepby(sample)
结果:
+------------------+
| sample id t |
|------------------|
1. | 1 40 1 |
2. | 1 40 2 |
3. | 1 40 3 |
4. | 1 180 2 |
5. | 1 180 3 |
|------------------|
6. | 2 10 1 |
7. | 2 10 2 |
8. | 2 90 2 |
9. | 2 90 3 |
10. | 2 90 4 |
11. | 2 90 5 |
|------------------|
12. | 3 100 1 |
13. | 3 100 2 |
14. | 3 100 3 |
15. | 3 155 1 |
16. | 3 155 2 |
+------------------+
其他一些观察:
您可以通过在 Stata 中设置计时器来检查 do 文件的哪些部分花费的时间最长。请参阅 timer
.
的帮助
sample
需要各种数据。如果id文件很大,可以考虑采用不需要排序的方法。 Fan et al.(1962)描述了具有此特征的抽样计划。
一个。顺序采样(风扇方法 1)。见 Chromy 第 1 (401) 页,1979
b。系统抽样
代替 n = 50 的随机样本,为 100 个样本中的每一个取 10 个大小为 5 的系统 sub-samples。每个样本都被视为一个集群,因此提供有效的标准误差。如果您可以根据信息对公司 ID 列表进行排序(例如,按大小、行业),则会产生进一步的优势。那么系统的sub-samples就会遍布整个列表。有关许多示例,请参见戴明 (1960)。'
参考资料
Chromy,JR。 1979. 顺序样本选择方法。美国统计协会调查研究方法部会议记录 401-406。可以在 http://www.amstat.org/sections/srms/Proceedings/papers/1979_081.pdf
找到
Deming WE (1960),商业研究样本设计,威利,纽约。
Fan, C. T.、Muller、Mervin E. 和 Rezucha, Ivan (1962),“使用顺序(逐项)选择开发抽样计划
技术和数字计算机”,美国统计协会杂志,57, 387-402。
我有一个大数据集,正因为它很大,所以我必须拆分它或一次加载一个变量。我已经加载了唯一标识符 id,我需要 select 随机 50 次观察 100 次。我搜索了一下,找到了 sample 和 runiform 来生成随机样本,但是我的问题是我需要生成 100 个样本,每个样本有 50 个观察值,因为我需要从整个数据集中采样,这个数据集很大,我只能保留一个变量内存,所以我需要将采样结果保存 100 次。我知道我可以使用 for 循环,但它效率不高,甚至 10 个循环也需要很多时间,有没有更快的方法来生成多个样本? 这是我的代码:
scalar i=0
forvalues i=1(1)100{
clear all
use generated/data1.dta
sample 50,count
save generated/sample`i'.dta,replace
merge 1:m id using generated/10m.dta
keep if _merge==3 |_merge==1
drop _merge
compress
save generated/sample`i'.dta,replace
}
我的原始文件是面板数据,我把原始文件分成几块以便处理,现在我需要 select 100 个随机样本,在代码中我用 for 循环做到了但是我认为这不是有效的方法。 为了更好地描述这个问题,我有一个每天观察价格、return、日期股息等的公司数据集,问题是原始文件非常大,因此要将它加载到内存中,我不得不将它拆分6 件,以便 Stata 可以加载它。现在我需要 select 100 个样本,每个样本有 50 个公司,我正在用这个周期来做:
***Generate 100 samples***
scalar i=0
forvalues i=1(1)100{
clear all
***Select 50 companies at random***
use generated/ids.dta
sample 50,count
***Merge with part1 of the original file***
merge 1:m permno using generated/ids10m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
***Keep in the both file all the ids***
save generated/both`i'.dta,replace
drop if date==.
***Fill the sample`i' with ids which have a correspondence with the date***
save generated/sample`i'.dta,replace
clear all
***Open the both file and keep only the non-match ids***
use generated/both`i'.dta,replace
keep if date==.
keep id
***Keep the non-matched ids to check at the end what's in there***
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id20m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
clear all
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id30m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id40m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id50m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
use generated/both`i'.dta,replace
keep if date==.
keep id
save generated/rplc`i'.dta, replace
merge 1:m id using generated/id60m.dta
keep if _merge==1 | _merge==3
drop _merge
compress
save generated/both`i'.dta,replace
drop if date==.
append using generated/sample`i'.dta
save generated/sample`i'.dta,replace
erase generated/both`i'.dta
erase generated/rplc`i'.dta
}
现在,这段代码的问题是创建 100 个样本大约需要 40 分钟,有没有更快的方法来做同样的事情?
这是一个事件研究,大小在这里不是问题,问题不在于采样而是循环的效率。
您的 do 文件中有一个地方需要改进:您正在对 600 次采样 ID 与 "big" 文件进行合并。这里的代码只需要对每个大文件进行一次合并,或者在您的情况下需要六个。诀窍是将样本数据从长格式重塑为宽格式,每个 id 一行,并为选择该 id 的样本提供指示符。将此文件与每个大数据集合并后,re-assemble 个样本。玩具示例有两个大文件和三个示例。
clear
/* Generate 1st BIG data set */
input id t
10 1
10 2
40 1
40 2
40 3
50 1
50 2
55 2
55 6
90 2
90 3
end
save big1, replace
* Generate 2nd BIG data set */
clear
input id t
90 4
90 5
100 1
100 2
100 3
140 1
140 2
143 2
155 1
155 2
180 2
180 3
end
save big2, replace
/* Generate three sample data sets-you'll do this with "sample" */
clear
input sample id
1 40
1 180
end
tempfile samp1
save `samp1'
clear
input sample id
2 10
2 90
end
tempfile samp2
save `samp2'
clear
input sample id
3 100
3 155
end
/* Step 1. Append all samples */
append using `samp1' `samp2'
order id sample
sort id sample
list
/* Step 2. Reshape Wide with one obs per id */
tempvar set
gen `set' = sample
reshape wide sample, i(id) j(`set')
tempfile t2
save `t2'
list
/* Step 3. Merge sample ids with each "big" data set
and append the results */
clear
tempfile t3
save `t3', emptyok replace
forvalues g = 1/2 {
use big`g', clear
merge m:1 id using `t2'
keep if _merge ==3
drop _merge
append using `t3'
save `t3', replace
}
sort id t
list, sepby(id)
/* Step 4: Reassemble samples with data into
one data set, saved in advance */
clear
/*temporary file to hold results */
tempfile allsamps
save `allsamps', emptyok
/* Cycle through samples: change 3 to n. of samples */
forvalues i = 1/3 {
use `t3', clear
gen sample = `i' if sample`i'==`i'
drop if sample==.
append using `allsamps'
save `allsamps', replace
}
drop sample?
order sample id
sort sample id t
save allsamples,replace
list, sepby(sample)
结果:
+------------------+
| sample id t |
|------------------|
1. | 1 40 1 |
2. | 1 40 2 |
3. | 1 40 3 |
4. | 1 180 2 |
5. | 1 180 3 |
|------------------|
6. | 2 10 1 |
7. | 2 10 2 |
8. | 2 90 2 |
9. | 2 90 3 |
10. | 2 90 4 |
11. | 2 90 5 |
|------------------|
12. | 3 100 1 |
13. | 3 100 2 |
14. | 3 100 3 |
15. | 3 155 1 |
16. | 3 155 2 |
+------------------+
其他一些观察:
您可以通过在 Stata 中设置计时器来检查 do 文件的哪些部分花费的时间最长。请参阅
timer
. 的帮助
sample
需要各种数据。如果id文件很大,可以考虑采用不需要排序的方法。 Fan et al.(1962)描述了具有此特征的抽样计划。
一个。顺序采样(风扇方法 1)。见 Chromy 第 1 (401) 页,1979
b。系统抽样
代替 n = 50 的随机样本,为 100 个样本中的每一个取 10 个大小为 5 的系统 sub-samples。每个样本都被视为一个集群,因此提供有效的标准误差。如果您可以根据信息对公司 ID 列表进行排序(例如,按大小、行业),则会产生进一步的优势。那么系统的sub-samples就会遍布整个列表。有关许多示例,请参见戴明 (1960)。'
参考资料
Chromy,JR。 1979. 顺序样本选择方法。美国统计协会调查研究方法部会议记录 401-406。可以在 http://www.amstat.org/sections/srms/Proceedings/papers/1979_081.pdf
找到Deming WE (1960),商业研究样本设计,威利,纽约。
Fan, C. T.、Muller、Mervin E. 和 Rezucha, Ivan (1962),“使用顺序(逐项)选择开发抽样计划 技术和数字计算机”,美国统计协会杂志,57, 387-402。