【发布时间】:2018-08-04 19:39:39
【问题描述】:
原始问题
在工作中导入大型数据集时,我注意到在使用 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 有148 个auto.dta 观察值,而auto2.dta 没有一个观察值。这表明相同(即第一个)数据集被附加了两次。这表明(对我而言)脚本的 append 部分工作正常,但本地 marco 存在问题,shtname。
* DEMONSTRATE APPEND 似乎可以工作 *
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
为了解决 cmets 中的一些注释,在控制台中输入 sysuse dir 时可以找到 auto2.dta。因此,它是一个可供所有人使用的数据集。我已尽我所能保持我的代码可复制,除非我弄错了,否则只需设置cd 以使上述代码正常工作。
其次,我努力确保我没有犯愚蠢的逻辑错误(如上所述,我意识到我在原始问题中省略了保存文件,这确实意味着我每次都附加一个空数据集) .也就是说,可能是我已经研究这个问题太久了,我再也看不到树上的木头了;所以,如果它仍然是单线类型的问题,请放轻松!
最后,我从来没有说过 Stata 忘记了本地宏,只是它似乎这样做了。因此,我问这个问题是为了了解发生了什么(或者更有可能是我在哪里犯了错误)。
***编辑#3
此图像似乎显示(至今)无法解释的行为源于append 而不是import。
【问题讨论】:
-
你到底想做什么?在已有工作表 1 的 Stata 数据集中追加工作表 2?看来您以错误的方式使用附加
-
@SeánMcK 你没有做任何与我提议的不同的事情。在循环的第一次迭代中附加一个空数据集没有意义。事实仍然是,您的想法存在逻辑错误。此外,您的本地宏观问题也没有任何意义。 Stata(出现)忘记了哪个宏?你还没有告诉我们。
-
所有本地宏都在我的电脑上正常显示。仅仅因为某些东西“有效”并不意味着它在逻辑上是正确的或良好的编程习惯。
-
如果在所有这些讨论之后你仍然看不出你的方法为什么不合逻辑,这与我无关。我之前评论的重点是黑客行为会产生意想不到的后果。您使用
append的方式可能与循环冲突。话虽如此,我想我会收工并专注于帮助那些认为我的答案有帮助的人。 -
@SeánMcK issue
return list在将它们复制到本地之前查看哪些 r 类结果保留在内存中。
标签: foreach append stata stata-macros