代码拉取完成,页面将自动刷新
同步操作将从 songbl/stata_do 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
*---------------------
*-3.5 循环语句
*---------------------
* ==本节目录==
* 3.5.1 while 语句
* 3.5.2 forvalues 语句
* 3.5.3 foreach 语句
*------------------
*-3.5.1 while 语句 (条件循环)
local j = 0
while `j'<5{
dis `j'
local j = `j'+1
}
*-或
local j = 0
while `j'<5{
dis `j++'
}
*----------------------------------
*-示例: 采用数值法求取函数的极小值 (self-reading)
twoway function y = 0.2*exp(x) - ln(x^2) + 3, ///
range(0 4) lw(*2)
local trace "set trace on" // 解析具体过程
*---------------------------------------------------begin------
local delta = 0.05 // 步长
local x = 1 // x 的初始值
local j = 0 // 计数器:记录迭代次数
local e = 1 // y1-y0
local e0 = 0.01 // 收敛判据
while `e' > `e0'{
`trace'
local y0 = 0.2*exp(`x') - ln(`x'^2) + 3
local x = `x' + `delta'
local y1 = (0.2*exp(`x') - ln(`x'^2)) + 3
local e = abs(`y1' - `y0')
dis in g "*" _c
local j = `j' + 1
}
dis "e = " `e'
dis "x = " `x' // x 的解
dis "y = " `y1' // y 的极小值
dis "j = " `j' // 迭代次数
*-图示:
twoway function y = 0.2*exp(x) - ln(x^2) + 3, ///
range(0 4) lw(thick) xline(`x') yline(`y1') ///
text(`=`y1'-0.5' `=`x'+0.8' "(`x',`y1')")
*---------------------------------------------------over-------
*- 练习:
* (1) 设定 (delta=0.1, e0=0.01),-trace- 计算过程
* (2) 尝试将 (delta=0.001, e0=0.0001),结果有何变化?
* (3) 若设定 (delta=0.02, e0=0.0001),能否收敛?
* (4) 若设定 x=2 为初始值,能否收敛?
*- 程序修改如下:
*--------------------------------------------------------
local h = 0.001 // 步长
local x = 1 // x 的初始值
local j = 0 // 计数器:记录迭代次数
local e = 1 // y1-y0
local e0 = `h'/10 // 收敛判据 (修改为动态数值)
while abs(`e')>`e0'{
// 修改:abs(`e')
local y0 = 0.2*exp(`x') - ln(`x'^2) + 3
local x = `x' + `h'
local y1 = (0.2*exp(`x') - ln(`x'^2)) + 3
local e = `y1' - `y0' // 此前 e = abs(`y1'-`y0')
if (`e' > 0){
local h = -`h' // 新增:反向搜索
}
dis in g "*" _c
local j = `j' + 1
}
dis "e = " `e'
dis "x = " `x' // x 的解
dis "y = " `y1' // y 的极小值
dis "j = " `j' // 迭代次数
*-图示:
local x: dis %4.3f `x' // 新增:显示的更美观
local y: dis %4.3f `y1'
twoway function y = 0.2*exp(x) - ln(x^2) + 3, ///
range(0 4) lw(thick) xline(`x') yline(`y1') ///
text(`=`y'-0.5' `=`x'+0.4' "(`x', `y')")
*--------------------------------------------------------
*- 练习:
* (1) 尝试初始值 x=3,是否能熟收敛?
* (2) 如何搜索更加有效?程序如何编写?
*-----------------------
*-3.5.2 forvalues 语句 (数字的循环)
forvalues j = 1/5{
dis `j'
}
local a = 0
forvalues i = 1(1)100{
local a = `a' + `i'
}
dis `a'
mat mm = J(10,3,0)
forvalues i = 1/10{
forvalues j = 1/3{
mat mm[`i',`j'] = `i' + `j'
}
}
mat list mm
*-示例 1:多个文件导入和合并
type d1.txt
type d2.txt
type d3.txt
*-导入
forvalues j = 1/3{
local v id year invest market stock
insheet `v' using d`j'.txt, clear
save s`j'.dta, replace
}
*-合并(纵向追加)
use s1.dta, clear
forvalues j = 2/3{
append using s`j'.dta
}
save alldata.dta, replace
*---------------------
*-3.5.3 foreach 语句 (变量、暂元、文件等的循环)
help foreach // 语法格式
*-a. 任意格式:foreach v in ...
type BMW.txt
type Benz.txt
type Audi.txt
foreach file in BMW Benz Audi{
local v id year invest market stock
insheet `v' using `file'.txt,clear
save `file'.dta, replace
}
* 追加样本
use BMW.dta, clear
foreach file in Benz.dta Audi.dta{
append using `file'
}
list,sepby(id)
*-b. 变量名循环:foreach v of varlist ...
*-示例 1:各变量的对数转换
sysuse auto,clear
global vars "price weight length"
foreach v of varlist $vars{
gen ln_`v' = ln(`v')
label variable ln_`v' "ln(`v')"
}
*-示例 2:各变量的缩尾处理(Winsorized)
sysuse nlsw88, clear
local vars "wage hours ttl_exp grade"
foreach v of varlist `vars'{
winsor `v' , gen(`v'_w) p(0.01)
}
sum wage* hours* ttl* grade*, sep(2)
*-c. 暂元循环:foreach cc of local ...
sysuse nlsw88, clear
local vars "wage hours ttl_exp grade"
foreach v of local vars{
winsor `v' , gen(`v'_w) p(0.01)
}
sum wage* hours* ttl* grade*, sep(2)
*-特别注意:这里的 vars 暂元在引用时无需加 `'
*-d. 数字循环:foreach num of numlist ...
foreach num of numlist 1 4/8 13(2)21 103 {
display in y _s(10) `num'
}
foreach s of numlist 111 1111 11111 111111 1111111 11111111{
dis in g _s(10) %16.0f `s'^2
}
*-这与 -forvalues- 语句有何差异?
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。