0

私の質問のタイトルは少しあいまいかもしれません。

以前は、「サブディレクトリの完全なリストを取得」して、これらのサブディレクトリ内のファイルを Stata に読み込みたいと考えていました (この投稿この投稿を参照)。

@Roberto Ferrer のすばらしい提案のおかげで、私はほとんどこれを行うことができました。しかし、私は別の問題に遭遇しました。個別のファイルが非常に多いため、ローカル マクロの長さが上限に達しているようです。コマンドの実行後、local n: word countStata はエラー メッセージを送信します。

マクロ置換により、行が長すぎます。

マクロを置換した結果の行は、許可されているよりも長くなります。最大許容長は 645,216 文字です。これは、セット maxvar に基づいて計算されます。これは、Stata/SE および Stata/MP で変更できます。以下は、Stata/SE または Stata/MP を使用している場合にのみ該当します。

行の最大長は、マクロの最大長 (現在は 645,200 文字) よりも 16 文字長く定義されています。set maxvar の単位が増加するたびに、長さの最大値が 129 ずつ増加します。set maxvar の最大値は 32,767 です。したがって、maxvar を最大値に設定すると、行の最大長は 4,227,159 文字まで設定できます。

r(920);

サブディレクトリの数を 5 に減らすと、Stata は正常に動作します。およそ 100 のサブディレクトリがあるので、アクションを 20 回複製するとします。まあ、それは管理可能ですが、このプロセスを完全に自動化できるかどうか、より具体的には、最大許容マクロ長を「使い果たす」ことができるかどうか、ファイルをインポートして次回サブディレクトリの別のグループを追加できるかどうかを知りたいです。

以下に私のコードを見つけることができます:

//====================================
//=== read and clean projects data ===
//====================================
version 14
set linesize 80
set more off

clear
macro drop _all
set linesize 200
cd G:\Data_backup\Soufang_data


*----------------------------------
* Read all files within dictionary
*----------------------------------


* Import the first worksheets 1:"项目首页" 2:"项目概况" 3:"成交详情"
* worksheet1

filelist, directory("G:\Data_backup\Soufang_data") pattern(*.xlsx)

* Add pattern(*.xlsx) provent importing add file type( .doc or .dta)

gen tag = substr(reverse(dirname),1,6) == "esuoh/"
keep if tag==1
gen path = dirname+"\"+filename
qui valuesof path if tag==1
local filelist = r(values)

split dirname, parse("\" "/")
ren dirname4 citylist
drop dirname1-dirname3 dirname5
qui valuesof citylist if tag==1
local city = r(values)

local count = 1
local n:word count `filelist'

  forval i = 1/`n' {
      local file    : word `i' of `filelist'
      local cityname: word `i' of `city'

      ** don't add xlsx after `file', suffix has been added
      ** write "`file'" rather than `file', I don't know why but it works
      qui import excel using "`file'",clear
      cap qui sxpose,clear
      cap qui drop in 1/1
      gen city = "`cityname'"


      if `count'==1 {
          save house.dta,replace emptyok
         }
      else          {
          qui append using house
          qui save house.dta,replace emptyok
          }

      local ++count
      } 

ありがとうございました。

4

1 に答える 1

2

ファイルのリスト全体をマクロに保存する必要はありません。filelist操作するファイルのデータベースを作成します。保存して、処理するファイルごとに再ロードするだけです。また、データセットを追加するために非常に非効率的な方法を使用しています。追加されたデータセットが大きくなるにつれて、再読み込みと保存のコストが非常に高くなり、プロセス全体が遅くなる可能性があります。

これは、Excel ファイルを処理する方法のスケッチです。

filelist, directory(".") pattern(*.xlsx)
save "myfiles.dta", replace

local n = _N

forval i = 1/`n' {

    use in `i' using "myfiles.dta", clear

    local f = dirname + "/" + filename

    qui import excel using "`f'",clear

    tempfile res`i'
    save "`res`i''"

} 

clear
forval i = 1/`n' {

    append using "`res`i''"

} 

save "final.dta", replace
于 2016-03-22T14:46:46.713 に答える