Stata:替换,如果,forvalues [英] Stata: replace, if, forvalues

查看:663
本文介绍了Stata:替换,如果,forvalues的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

use "locationdata.dta", clear
gen ring=.
* Philly City Hall
gen lat_center = 39.9525468
gen lon_center = -75.1638855
destring(INTPTLAT10), replace
destring(INTPTLON10), replace
vincenty INTPTLAT10 INTPTLON10 lat_center lon_center , hav(distance_km) inkm
quietly su distance_km
local min = r(min)
replace ring=0 if (`min' <= distance_km < 1)
local max = ceil(r(max))
* forval loop does not work
forval i=1/`max'{
    local j = `i'+1
    replace ring=`i' if (`i' <= distance_km < `j')
}

我从一个点开始画1公里的圆环。代码的最后一部分( forval )不起作用。这里有什么不对吗?

I am drawing rings by 1 km from a point. The last part of the code (forval) does not work. Something wrong here?

编辑:

<$ c的结果$ c> forval 部分内容如下:

. forval i=1/`max'{
2.         local j = `i'+1
3.         replace ring=`i' if `i' <= distance_km < `j'
4. }
(1746 real changes made)
(0 real changes made)
(0 real changes made)
(0 real changes made)
....

因此,替换不适用于 i = 2 及以后。

So, replacing does not work for i = 2 and beyond.

推荐答案

双重不等式,例如

(`min' <= distance_km < 1)

$ b $根据数学惯例有意义的b

在Stata中显然是合法的。否则,您的代码将触发语法错误。但是,在评估整个表达式之前,Stata不会进行评估。这里的括号是无关紧要的,因为关键是如何评估它们的内容。事实证明,结果不太可能是你想要的。

which makes sense according to mathematical conventions is clearly legal in Stata. Otherwise, your code would have triggered a syntax error. However, Stata does not hold evaluation until the entire expression is evaluated. The parentheses here are immaterial, as what is key is how their contents are evaluated. As it turns out, the result is unlikely to be what you want.

更详细:Stata从左到右解释此表达式,如下所示。第一个相等

In more detail: Stata interprets this expression from left to right as follows. The first equality

`min' <= distance_km

是真还是假,因此被评估为0或1.显然你想选择这样的值

is true or false and thus evaluated as 0 or 1. Evidently you want to select values such that

distance_km >= `min' 

对于此类值,上述不等式是真的并且返回1.然后Stata将1前进的结果转向第二个不等式,评估

and for such values the inequality above is true and returns 1. Stata would then take a result of 1 forward and turn to the second inequality, evaluating

1 < 1 

(即第一次不平等的结果< 1 ),但这对于这些值是错误的。相反,

(i.e. result of first inequality < 1), but that is false for such values. Conversely,

(`min' <= distance_km < 1)

将被评估为

 0 < 1 

- 这是真的(返回1) - 当且仅当

-- which is true (returns 1) -- if and only if

 `min' > distance_km 

简而言之,你打算用不同的方式表达,即

In short, what you intend would need to be expressed differently, namely by

  (`min' <= distance_km) & (distance_km < 1)

我猜想这是你问题的根源。

I conjecture that this is at the root of your problem.

请注意,Stata有一个 inrange()函数,但它不是你想要的。

Note that Stata has an inrange() function but it is not quite what you want here.

但是,所有这一切,从查看你的代码来看,不等式和循环都显得非常不必要。你希望你的戒指间隔1公里,所以

But, all that said, from looking at your code the inequalities and your loop both appear quite unnecessary. You want your rings to be 1 km intervals, so that

 gen ring = floor(distance_km) 

可以在您调用 vincenty 后替换整个代码块,因为 floor()向下舍入整数结果。你似乎知道它的双胞胎 ceil()

can replace the entire block of code after your call to vincenty, as floor() rounds down with integer result. You appear to know of its twin ceil().

其他一些小点,偶然但值得注意:

Some other small points, incidental but worth noting:


  1. 您可以一次 destring 多个变量。

将常量放在带有 generate 的变量中是效率低下的。为此,请使用标量。 (但是,如果 vincenty 需要变量作为输入,那将覆盖此点,但它指出 vincenty 也是严格。)

Putting constants in variables with generate is inefficient. Use scalars for this purpose. (However, if vincenty requires variables as input, that would override this point, but it points up that vincenty is too strict.)

总结,meanonly 更适合计算最小值和最大值。选项名称无疑是误导性的。请参见 http://www.stata-journal.com/sjpdf.html?articlenum= st0135 供讨论。

summarize, meanonly is better for calculating just the minimum and maximum. The option name is admittedly misleading here. See http://www.stata-journal.com/sjpdf.html?articlenum=st0135 for discussion.

作为一般Stata的做法,你的帖子应该解释用户所写的 vincenty 来自,虽然在这种情况下似乎与此无关。

As a matter of general Stata practice, your post should explain where the user-written vincenty comes from, although it seems that is quite irrelevant in this instance.

为了完整性,这里是重写,尽管您需要根据数据进行测试。

For completeness, here is a rewrite, although you need to test it against your data.


 use "locationdata.dta", clear
 * Philly City Hall
 scalar lat_center = 39.9525468
 scalar lon_center = -75.1638855
 destring INTPTLAT10 INTPTLON10, replace
 vincenty INTPTLAT10 INTPTLON10 lat_center lon_center , hav(distance_km) inkm
 gen ring = floor(distance_km)

这篇关于Stata:替换,如果,forvalues的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆