原始问题
在导入工作中的大型数据集时,我注意到一些意外行为,其中在使用append
命令时,Stata似乎“忘记”了本地宏。
这似乎更奇怪,因为这似乎是该命令所特有的现象(我用save
测试了,并且代码按预期工作了)。
*****************
** SET UP
******************
local datasets "auto.dta auto2.dta"
global data "/Users/Seansmac/Desktop/stata_question"
save "$data/test_data.dta", replace emptyok
local datasets "auto.dta auto2.dta"
** Save Stata data in two Excel sheets. This replicates the status of my raw data at work.
foreach dataset in `datasets'{
di "`dataset' loaded"
sysuse `dataset', clear
gen data_name = "`dataset'"
tab data_name
export excel using "$data/auto_excel.xlsx", sheet("`dataset'") first(variables) sheetreplace
di "`dataset' saved in excel"
}
*****************
** Demo of Problem
******************
import excel "$data/auto_excel.xlsx", desc
local worksheets `r(N_worksheet)'
di `worksheets'
forvalues i = 1/`worksheets' {
di " Sheet number `i'"
local shtname`i' `r(worksheet_`i')'
di "loading database: `shtname`i''"
import excel "$data/auto_excel.xlsx", sheet("`shtname`i''") clear firstrow
di "database: `shtname`i'' loaded"
append using "$data/test_data.dta", force
di "database: `shtname`i'' appended"
}
***** Show only the same data was appended twice
use "$data/test_data.dta", clear
tab data_name
** I include this tab to demonstrate that only one of the two data sets is appended.
*****************
** END
*****************
很抱歉,示例比较混乱,但是我经常发现在与本地人一起工作时使用display
会有所帮助。要运行代码,所需要做的就是更改全局数据。
为了保持对工作中问题的忠诚,我加入了import excel
部分;我对问题的理解不足,无法使示例变得更简单。
已修改原始问题
下面是两个代码块。第一个示例证明append
命令似乎可以按预期运行(我注意到我在最初的问题中忘记使用save
)。此块说明尽管将数据集附加空数据集可能并不完全直观,但仍可以正常工作。此方法的优点是,它在加载文件时无需使用条件语句。
在第二个代码块中,我尝试以相同的基本方式使用append
命令,但这一次是循环的。此代码块是从Pearly Spencer复制并粘贴的,只有三个小改动:
if
语句注释掉append
使用了空的数据集(然后是save
,因此第二次不应该为空)。 Stata“忘记”的本地宏为shtname
。如果您检查display
语句,则在第一个循环之后将不输出。这是我的问题所在。为了进一步说明这一点,脚本结尾处的tab
命令显示变量data_name
具有auto.dta
的148个观测值,而没有一个auto2.dta
中的。这表明相同(即第一个)数据集被追加了两次。 (对我来说)这表明脚本的append
部分工作正常,但是本地marco shtname
存在问题。
*演示附件出现在工作中*
clear all
cd "[**INSERT CD**]"
*Create empty data set to append later
save "test_data_noloop.dta", replace emptyok
* load first dataset
sysuse auto.dta, clear
* Gen a variable indicating what dataset it is
gen dataset = "auto_1"
* append data with empty dataset
append using "test_data_noloop.dta"
save "test_data_noloop.dta", replace
clear
*load second dataset
sysuse auto2.dta, clear
* gen dataset variable again
gen dataset = "auto_2"
* append with the previously saved dataset
append using "test_data_noloop.dta"
* Demonstrate both datasets have been appended
tab dataset
*带有小调整功能的Pearly Spencer *
clear all
cd "[**INSERT CD**]"
local datasets "auto.dta auto2.dta"
** Added the following line
save "test_data.dta", replace emptyok
foreach dataset in `datasets'{
display "`dataset' loaded"
sysuse `dataset', clear
generate data_name = "`dataset'"
tab data_name
export excel using "auto_excel.xlsx", sheet("`dataset'") first(variables) sheetreplace
display "`dataset' saved in excel"
}
import excel "auto_excel.xlsx", desc
local worksheets `r(N_worksheet)'
display `worksheets'
forvalues i = 1 / `worksheets' {
display " Sheet number `i'"
local shtname`i' `r(worksheet_`i')'
display "loading database: `shtname`i''"
import excel "auto_excel.xlsx", sheet("`shtname`i''") clear firstrow
*if `i' == 1 save "test_data.dta", replace
display "database: `shtname`i'' loaded"
*if `i' > 1 {
append using "test_data.dta", force
save "test_data.dta", replace
*}
display "database: `shtname`i'' appended"
}
use "test_data.dta", clear
tab data_name
要解决注释中的某些问题,在控制台中键入sysuse dir
时可以找到auto2.dta。因此,它是所有人都可以使用的数据集。我已尽力使我的代码具有可复制性,除非我没有记错,所有要做的就是将cd
设置为上述代码才能正常工作。
其次,我尽力确保没有发生愚蠢的逻辑错误(如上所述,我意识到我没有在最初的问题中保存文件,这的确意味着我每次都附加一个空的数据集) 。就是说,可能是我一直在研究这个问题的时间如此之久,以至于我再也看不到树木上的木头了。因此,如果仍然是一种衬纸类型问题,请放轻松!
最后,我从未说过Stata会忘记本地宏,仅仅是因为它出现了。因此,我问这个问题是为了了解发生了什么(或更可能是我在哪里犯了错误)。
***编辑#3
该图像似乎表明(至今)无法解释的行为源自append
而非import
。
答案 0 :(得分:1)
我的理解是,您希望将连续的Excel工作表追加到一个Stata数据集中。
下面是您的玩具示例的有效版本。
设置:
clear all
local datasets "auto.dta auto2.dta"
将Stata数据保存在两个Excel工作表中:
foreach dataset in `datasets'{
display "`dataset' loaded"
sysuse `dataset', clear
generate data_name = "`dataset'"
tab data_name
export excel using "auto_excel.xlsx", sheet("`dataset'") first(variables) sheetreplace
display "`dataset' saved in excel"
}
演示该问题的解决方案:
import excel "auto_excel.xlsx", desc
local worksheets `r(N_worksheet)'
display `worksheets'
forvalues i = 1 / `worksheets' {
display " Sheet number `i'"
local shtname`i' `r(worksheet_`i')'
display "loading database: `shtname`i''"
import excel "auto_excel.xlsx", sheet("`shtname`i''") clear firstrow
if `i' == 1 save "test_data.dta", replace
display "database: `shtname`i'' loaded"
if `i' > 1 {
append using "test_data.dta", force
save "test_data.dta", replace
}
display "database: `shtname`i'' appended"
}
显示结果:
use "test_data.dta", clear
tab data_name
(为了获得更好的可读性,我将代码分成不同的片段)
编辑:
Stata一次只能use
一个数据集。 append
命令的工作方式是将数据从指定的外部数据集“附加”到已经加载到内存中的数据(即use
d)。您的示例版本无法提供理想结果的原因是,您每次导入Excel工作表后都试图追加一个空数据集。这是逻辑上的错误。
编辑2:
生成的输出:
. clear all
. local datasets "auto.dta auto2.dta"
.
. foreach dataset in `datasets'{
2. display "`dataset' loaded"
3. sysuse `dataset', clear
4. generate data_name = "`dataset'"
5. tab data_name
6. export excel using "auto_excel.xlsx", sheet("`dataset'") first(variables) sheetreplace
7. display "`dataset' saved in excel"
8. }
auto.dta loaded
(1978 Automobile Data)
data_name | Freq. Percent Cum.
------------+-----------------------------------
auto.dta | 74 100.00 100.00
------------+-----------------------------------
Total | 74 100.00
file auto_excel.xlsx saved
auto.dta saved in excel
auto2.dta loaded
(1978 Automobile Data)
data_name | Freq. Percent Cum.
------------+-----------------------------------
auto2.dta | 74 100.00 100.00
------------+-----------------------------------
Total | 74 100.00
file auto_excel.xlsx saved
auto2.dta saved in excel
.
. import excel "auto_excel.xlsx", desc
Sheet | Range
----------+----------
auto.dta | A1:M75
auto2.dta | A1:M75
.
. local worksheets `r(N_worksheet)'
. display `worksheets'
2
.
. forvalues i = 1 / `worksheets' {
2. display " Sheet number `i'"
3. local shtname`i' `r(worksheet_`i')'
4. display "loading database: `shtname`i''"
5. import excel "auto_excel.xlsx", sheet("`shtname`i''") clear firstrow
6. if `i' == 1 save "test_data.dta", replace
7. display "database: `shtname`i'' loaded"
8. if `i' > 1 {
9. append using "test_data.dta", force
10. save "test_data.dta", replace
11. }
12. display "database: `shtname`i'' appended"
13. }
Sheet number 1
loading database: auto.dta
file test_data.dta saved
database: auto.dta loaded
database: auto.dta appended
Sheet number 2
loading database: auto2.dta
database: auto2.dta loaded
(note: variable rep78 was byte in the using data, but will be str9 now)
file test_data.dta saved
database: auto2.dta appended
.
. use "test_data.dta", clear
. tab data_name
data_name | Freq. Percent Cum.
------------+-----------------------------------
auto.dta | 74 50.00 50.00
auto2.dta | 74 50.00 100.00
------------+-----------------------------------
Total | 148 100.00
.
end of do-file