2014-10-14 5 views
-2

Я хочу, чтобы заменить этот код с петлей:значения с помощью цикла Stata последовательно

replace var1=1 if year > 1996 & st==5 
replace var1=0 if year < 1996 & st==5 
replace var1=1 if year > 1998 & st==6 
replace var1=0 if year < 1998 & st==6 

Мои данные выглядит следующим образом

st year var 
5 1993 
5 1996 
5 1992 
6 1991 
6 1999` 

Я написал цикл, как этот

foreach st in 5 6} 
    foreach yr in 1996 1998 } 
    replace var1=1 if year>`yr' & state==`st' 
    replace var1=0 if year<`yr' & state==`st' 
} 
} 

Однако этот цикл не дает результатов, аналогичных ручному методу. Я знаю, что делаю глупую ошибку.

EDIT:

Для дальнейшего уточнения моего фактического кода, который я написал (без петель) выглядит, как показано ниже. Я хотел бы использовать цикл или другой более простой способ, чтобы прийти к тем же результатам:

gen policy=. 
replace policy=1 if year>1996 & fipscode==5 
replace policy=0 if year <1997 & fipscode==5 

replace policy=1 if year>1995 & fipscode==6 
replace policy=0 if year <1996 & fipscode==6 

replace policy=1 if year>1997 & fipscode==9 
replace policy=0 if year <1998 & fipscode==9 

replace policy=1 if year>1997 & fipscode==15 
replace policy=0 if year <1998 & fipscode==15 

replace policy=1 if year>1992 & fipscode==16 
replace policy=0 if year <1993 & fipscode==16 

replace policy=1 if year>1996 & fipscode==31 
replace policy=0 if year <1997 & fipscode==31 

replace policy=1 if year>1997 & fipscode==32 
replace policy=0 if year <1998 & fipscode==32 

replace policy=1 if year>1996 & fipscode==39 
replace policy=0 if year <1997 & fipscode==39 

replace policy=1 if year>1997 & fipscode==40 
replace policy=0 if year <1998 & fipscode==40 

replace policy=1 if year>1992 & fipscode==54 
replace policy=0 if year <1993 & fipscode==54 
+0

Я исправил тривиальный промах, запутывающий 6 и 7. Я оставил основной сегмент кода в вашем вопросе точно так же, как и в сообщении. Обратите внимание, что вам нужно оставить скобку '{' в начале каждого цикла, а не в правой скобе '}'. –

+0

К сожалению, трудно понять, что этот вопрос может помочь кому угодно, кроме оригинального плаката. Это объясняет мой нижний план. –

+0

Дополнительный пример (после EDIT :) еще труднее работать. Лучше всего просто работать в обратном направлении: какие условия должны быть закодированы 1, а какие закодированы 0? Обычно существует довольно простой способ кодирования переменных. Условие в 'fipscode' сводится к' if inlist (fipscode, 5,6,9,15,16,31,32,39,40,54) ', хотя существует ограничение на количество аргументов, которые будут выполняться функцией , за исключением того, что, по-видимому, существуют разные определения для разных лет. Иногда сложный набор определений просто означает сложный код. –

ответ

0

Попробуйте forvalues (я думаю, что это является эффективным по сравнению с foreach)

forvalues st=5/6{ 
    forvalues yr= 1996(2)1998{ 
     replace var1=1 if year>`yr' & state==`st' 
     replace var1=0 if year<`yr' & state==`st' 
    } 
} 

Если вы хотите придерживаться foreach:

foreach st of numlist 5/6{ 
    foreach yr of numlist 1996(2)1998{ 
     replace var1=1 if year>`yr' & state==`st' 
     replace var1=0 if year<`yr' & state==`st' 
    } 
} 
+1

Метрики верны. 'forvalues' более эффективен, чем' foreach' всякий раз, когда есть эквивалент. Это было бы тривиально здесь, но всегда стоит отметить. –

0

Похоже, у вас есть какой-то предопределено year сопоставляется некоторые предопределено st. В примере: 1996 с 5 и 1998 с 7. Если нет, то я неправильно понял вашу проблему. Если да, то вы можете перебирает параллельные списки:

clear 
set more off 

*----- example data ----- 

input /// 
st year 
5 1993 
5 1996 
5 1992 
7 1991 
7 1999 
end 

list 

*----- what you want ----- 

gen var1 = . 

local ylev 1996 1998 
local slev 5 7 
local n : word count `ylev' 

forvalues i = 1/`n' { 

    local y : word `i' of `ylev' 
    local s : word `i' of `slev' 

    replace var1 = 1 if year > `y' & st == `s' 
    replace var1 = 0 if year < `y' & st == `s' 

} 

list 

мне очень интересно, почему ни один из ваших условий не содержит =, выходя из дела.

+0

Хороший комментарий о игнорировании случая равенства, который является фокусом моего ответа, размещенного более или менее одновременно. –

0

Код может быть более или менее произвольным кодом, разработанным для изучения техники, но пример действительно странный. Даже если смысл состоит в том, чтобы просто изучить технику, нужно уделить еще один урок.

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

Испытание year против 1996 года, а затем year по сравнению с 1998 годом требует некоторого анализа. Немного странно, что значения 1996 и 1998 годов сами игнорируются, поскольку оба > и < исключают ==, но код вместе имеет значение для таких значений.

Оставив в стороне первый вопрос, что это state, пешеход анализ показывает, что

  1. Наблюдения с year менее 1996 кодируются 0 первый раз, и остается 0 второй раз вокруг петли.

  2. Наблюдения с year, равные 1996 году, игнорируются в первый раз, но закодированы в течение 0 секунд вокруг цикла.

  3. Наблюдения с year, равные 1997 году, сначала кодируются 1, а восстанавливаются до 0 секунд.

  4. Наблюдения с year, равные 1998, кодируются 1 в первый раз, но игнорируются второй раз.

  5. Замечания с year больше 1998 года кодируются 1 в первый раз и сбрасываются на 1 секунду. (Это включает в себя любые пропущенные значения на year.)

Приведение в переменной state, значения, кроме 5 или 6 игнорируются. Поэтому

Вся двойная петля стягивается в одном операторе

replace var1 = year >= 1998 & inlist(state, 5, 6) 

и шесть линий становятся один.

EDIT: Дополнительный пример, как представляется, сводится к

gen policy = . 
replace policy = (year>1996) if inlist(fipscode, 5, 31, 39) 
replace policy = (year>1995) if fipscode==6 
replace policy = (year>1997) if inlist(fipscode, 9, 15, 32, 40) 
replace policy = (year>1992) if inlist(fipscode, 16, 54) 

, но не похоже, чтобы цикл в любом полезным способом.

+0

Чтобы уточнить, я хочу, чтобы var1 = 1, если выполнены два условия. и я хотел бы иметь эти 2 условия в цикле. эти два условия будут поступать из двух списков. например var1 = 1, если условие 1 в списке (a) == var2 и условие 1 в списке (b) = var = 3. предположим, что var 2 и 3 уже находятся в наборе данных как два столбца. – rrodrigorn0

+0

Извините, это ничего не разъясняет для меня без проработанного примера. Если вы не найдете ошибку в моей логике, что еще вы хотите сделать, это еще одна проблема. –

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