2014-12-06 2 views
0

Я только что начал изучать Stata, и мне тяжело. Моя проблема заключается в следующем: у меня есть две разные переменные: ATC и A, где A потенциально является подстрокой ATC. Теперь я хочу отметить все наблюдения, в которых A является подстрокой ATC с OK = 1.Stata Вложенное сравнение подстроки в foreach

Я попытался это с помощью простого вложенного цикла:

foreach x in ATC { 
foreach j in A { 
     replace OK = 1 if strpos(`x',`j')!=0 
    } 
} 

Однако всякий раз, когда я запускаю этот цикл изменений не, вносимый несмотря на то, должно быть много. Мне кажется, что я должен, вероятно, указать указатель, который изменяет OK (тот, который принадлежит ATC/x), но я понятия не имею, как это сделать. Это, наверное, очень просто, но я боролся с ним в течение некоторого времени.


Я должен уточнить: мой A список отдельно от основного списка (просто добавленным к нему) и содержит только уникальные ключи, которые я использую, чтобы определить ATC с, что я хочу. Поэтому у меня есть ~ 120 A -keys и пара миллионов ATC ключей. То, что я хотел сделать, это перебрать каждый ключ ATC для каждой отдельной клавиши A и пометить те ATC-ключами с A, которые подпадают под действие.

Это означает, что у меня нет полных наборов (ATC, A, OK), а вместо этого отдельные списки разных размеров. Например: у меня есть

ATC OK A 
ABCD 0 . 
EFGH 0 . 
... ... ... 
.  . AB 
.  . ET 

и хотите результат, который "ABCD", имеющий OK помечен как 1 в то время как "EFGH" остается на 0.

ответ

5

Мы можем ответить на ваш вопрос на две части. Ваше название подразумевает проблему с циклами, но ваши петли эквивалентны только

replace OK = 1 if strpos(ATC, A)!=0 

поэтому использование петли кажется несущественным. Это оставляет сравнение подстроки.

Давайте поставлять пример:

. set obs 3 
obs was 0, now 3 

. gen OK = 0 

. gen A = cond(_n == 1, "42", "something else") 

. gen ATC = "answer is 42" 

. replace OK = 1 if strpos(ATC, A) != 0 
(1 real change made) 

. list 

    +------------------------------------+ 
    | OK    A   ATC | 
    |------------------------------------| 
1. | 1    42 answer is 42 | 
2. | 0 something else answer is 42 | 
3. | 0 something else answer is 42 | 
    +------------------------------------+ 

Так оно работает отлично; и вам действительно нужно дать воспроизводимый пример, если вы считаете, что у вас что-то другое.

Что касается указания, где переменная должна быть изменена: ваш код делает именно это, как показывает приведенный выше пример.


Обновление устраняет проблему. Stata будет смотреть только в том же наблюдении для соответствующей подстроки, когда вы укажете синтаксис, который вы дали. Переменная в Stata - это поле в наборе данных.Для цикла по набору значений, что-то вроде этого должно хватить

gen byte OK = 0 
levelsof A, local(Avals) 

quietly foreach A of local Avals { 
    replace OK = 1 if strpos(ATC, `"`A'"') > 0 
} 

Примечания:

  1. Указание byte вырубает хранения.

  2. Возможно, вам понадобится ограничение if или in на levelsof.

  3. quietly вырезает сообщения об изменении значений. При отладке часто лучше не учитывать.

  4. > 0 может быть опущен, так как положительный результат от strpos() автоматически рассматривается как истинный в логических сравнениях. См. this FAQ.

+0

Я отредактировал свое оригинальное сообщение. Я, вероятно, должен был привести пример с самого начала, спасибо за вашу помощь в любом случае. Я прошу прощения за мое плохое форматирование и т. Д., Так как я не очень сильно использую этот сайт. – user2299050

+0

Удалить «возможно». Теперь проблема очевидна. –

+0

Спасибо за закрытие! –

Смежные вопросы