2

stata のマクロで作成した手動リストがあります。

global list1 "a b c d"

後で次のようなものを繰り返します

foreach name in $list1 {
action
}

リストが大きくなり、急速に変化しているため、これをDB主導のリストに変更しようとしています。次のコマンドで新しい $list1 を作成します

odbc load listitems=items, exec("SELECT items  from my_table")  
levelsof listitems
global list1=r(levels)

それぞれの項目は同じですが、このリストは異なるようで、項目が多すぎるとforループで壊れてエラーが発生します

{ required
r(100);

また、レベルのリストアイテムのみを実行すると、出力が得られます

`"a"' `"b"' `"c"' `"d"' 

これは、他のマクロとは少し異なります。

私はしばらくこれで立ち往生しています。繰り返しますが、アイテムの数が多くなった場合 (15 以上) にのみ失敗します。

4

1 に答える 1

7

解決策 1:

levelsof listitems, clean local(list1)
foreach name of local list1 {
    ...action with `name'...
}

解決策 2:

levelsof listitems, clean
global list1 `r(levels)'
foreach name of global list1 {
    ...action with `name'...
}

説明:

入力するとき

foreach name in $list1 {

$list1 にあるものは何でも、Stata がそれを見る前にインラインで置換されます。グローバル マクロ list1 に非常に長いリストが含まれている場合、Stata は

foreach name in a b c d e .... very long list of things here ... {

グローバルまたはローカル マクロにリストがあり、それらをループしたいことを Stata に伝える方が効率的です。コマンドラインでそれらを展開する必要はありません。それが

foreach name of local list1 {

foreach name of global list1 {

です。foreach のその他の機能については、-help foreach- を参照してください。

また、あなたはもともとコーディングしました

levelsof listitems
global list1=r(levels)

そして、あなたは見たことに気づきました

`"a"' `"b"' `"c"' ...

結果として。これらは、Stata が「複合引用符付き」文字列と呼んでいるものです。複合引用符付き文字列を使用すると、引用符を効果的にネストできます。だから、あなたは次のようなものを持つことができます

`"This is a string with `"another quoted string"' inside it"'

あなたはそれを必要としないと言ったので、levelsof の「クリーン」オプションを使用して、結果を引用しないようにすることができます。(このオプションの詳細については、-help levelsof- を参照してください。) また、(r(levels) にある) levelsof の返された結果を後でグローバル マクロに割り当てていました。-levelsof- には、実際には -local()- という名前のオプションがあり、ローカル (グローバルではない) マクロの名前を指定して、結果を直接入れることができます。したがって、次のように入力するだけです。

levelsof listitems, clean local(list1)

複合引用符を省略し、結果を list1 という名前のローカル マクロに直接配置します。

最後に、何らかの理由でその local() オプションを使用したくない場合や、リストをグローバル マクロに入れておきたい場合は、コーディングする必要があります。

global list1 `r(levels)'

それよりも

global list1=r(levels)

違いは、後者が r(levels) を関数として扱い、それを Stata の文字列式パーサーで実行することです。Stata では、文字列 (文字列を含むマクロではなく、文字列) に 244 文字の制限があります。一方、文字列を含むマクロには、何千もの文字を含めることができます。したがって、r(levels) に 244 文字を超える文字がある場合、

global list1=r(levels)

list1 に格納された結果を 244 文字で切り捨てることになります。

代わりにコーディングする場合

global list1 `r(levels)'

r(levels) の内容は、コマンドが実行される前にインラインで展開されます。それで、Stataは見ます

global list1 a b c d e ... very long list ... x y z

マクロ名 (list1) の後のすべては、その長さに関係なく、そのマクロ名にコピーされます。

于 2011-06-21T18:09:46.947 に答える