2

この質問は、純粋に知的好奇心から出たものです。

Python のセクションを比較的頻繁に参照していると、これに似た質問がいくつか見られます。このような質問では、グローバル変数をプログラムで定義する方法を誰かが求めています。の落とし穴を知っている人もいれば、知らexecない人もいます。

ただし、私は最近、Stata でプログラミングを行っています。ここでは、次のことが一般的です。

local N = 100
local i = 1

foreach x of varlist x1 - x`N' {
    local `x' = `i' * `i'
    ++i 
}

Stata の用語では、 という名前のローカル マクロNが作成され、N100 に評価されます。foreachループの各反復で、 ~ からの値x1x100ローカル マクロ に割り当てられxます。次に、ループ内の行はi、 の展開にの 2 乗を代入します。xこれは、 と同じ末尾を持つローカル マクロiです。つまり、このループの後、x44^2 にx88展開され、88^2 に展開されます。

Python では、同様のことを行う方法は次のようになります。

squares = {}

for x in range(1,101):
    squares[x] = x**2

次に、squares[7]7^2 に等しくなります。

これはかなり単純な例です。stata マクロには他にも多くの用途があります。評価する関数を渡す方法としてこれらを使用できます。たとえば、次のようになります。

local r1 "regress"
local r2 "corr"

foreach r of varlist r1-r2 {
     ``r'' y x
}

周りの二重の目盛りは、rそのマクロを 2 回、最初にr1/r2に、次にregress/に展開し、従属変数および独立変数としてcorr線形回帰を実行した結果、およびとの間の相関を示します。さらに複雑なものも可能です。yxyx

私の質問は基本的に、変数の割り当て/評価がこの形式の「マクロ割り当て/展開」をとる言語のより大きなカテゴリにstataが分類されますか? 言語がこのように設計される理由の説明、および/または他の言語での同様の構成の例に対するボーナスポイント。

4

4 に答える 4

3

それは実際には、糖衣構文がどれだけあるかという問題です。その価値のある言語では、マップまたは辞書のデータ構造を使用して、実行時に何らかの値を持つ変数名(キー)を作成できます。一部の言語は、他の言語よりも透過的に通常の変数識別子と統合する場合があります。

于 2011-03-04T04:48:44.597 に答える
3

(申し訳ありませんが、これはコメントではなく「回答」です....人々は私の回答を評価していないため、質問にコメントするのに十分なポイントがありません。)

まず、Stata の奇妙な点は、そのコード行を実行する前にマクロを変換することです。例えば:

タイプするとします。

local x3 = 20 
local y = 3 
display "I am `x`y'' years old"

内部的には、Stata はローカルを (内部から外部へ) 変換してから、コマンド実行しdisplayます。つまり、Stata はコマンドを翻訳します。

display "I am `x3' years old"

それから

display "I am 20 years old"

次に、Stata は実際にこの最後のコード行を実行します。最初にこのコマンドを実行すると、これらすべてを見ることができます: set trace on.

微妙な違いがあります。` 'ブラケットはコマンドを変更します。これは実際に他のプログラミング言語とは違うと思います。他の言語では 2 行のコード (1 行はマクロを「展開」するため、もう 1 行はコード行を実行するため) を必要とするところを、Stata では 1 行のコードで実行できることがよくあります。

これの便利な点は、Stata が` '括弧内のすべての種類の式を評価できることです (数値または文字列を返す限り...たとえば、行列を返すものは何もありません)。

display "I am `= 2011 - 1991' years old"
display "I am `= floor(uniform()*`x`y'')' years old"

これは慣れると非常に便利です。マクロは、たとえば SAS で行うよりも、Stata で物事をよりクリーンにします。SAS の%let声明はそれほど柔軟ではありません。

また、いくつかの間違いを指摘するつもりでした。

(1) これらの例では、ループの設定が間違っています。x1, x2, ... , x100 変数ではなく、マクロ (ローカル) です。は変数リストではないので、なんともforeach x of varlist x1 - x100言えません。x1-x100私がそれをやろうとしていたなら、おそらく次のものを使うでしょう:

local N = 100
forvalues i = 1/`N' {
    local x`i' = `i' * `i'
}

2 番目の例でも同じ間違いを犯しています。 変数ではありませんr1r2あなたはこれを行うことができます:

local mycommands regress corr 
foreach r in `mycommands' {
     `r' y x
}

(ただし、実際には同等の を入力しますがforeach r of local mycommands { ... }、これは実行がはるかに高速であると思われます)。

(2) 第二に、 ++i 有効ではありません。あなたはおそらく言うつもりlocal ++iでした。

于 2011-03-04T16:17:31.377 に答える
2

これがあなたが探しているものかどうかはわかりませんが、PHP では次のことができます。

for ($i=0; $i<10; $i++) {
    ${x.$i} = $i*$i;
}

print $x3; // prints 9
print $x4; // prints 16

私は個人的にこれを非常に不快に感じています。

于 2011-03-04T04:53:10.380 に答える
1

Javascript は明らかな例ですが、メカニズムは Python に似ており、Stata ではありません。

for(var i = 0; i < 100; i++)
    this["var" + i] = i * i;

alert(var8); // 64
于 2011-03-04T04:51:10.600 に答える