2016-11-22 5 views
2

Этот вопрос относится к Stata: select the minimum of each observation.Выберите самое низкое значение для каждой группы

У меня есть данные следующим образом:

clear 
input str4 id int eventdate byte dia_bp_copy int sys_bp_copy 
"pat" 15698 100 140 
"pat" 16183 80 120 
"pat" 19226 98 155 
"pat" 19375 80 130 
"sue" 14296 80 120 
"sue" 14334 88 127 
"sue" 14334 96 158 
"sue" 14334 84 136 
"sue" 14403 86 124 
"sue" 14403 88 134 
"sue" 14403 90 156 
"sue" 14403 86 134 
"sue" 14403 90 124 
"sue" 14431 80 120 
"sue" 14431 80 140 
"sue" 14431 80 130 
"sue" 15456 80 130 
"sue" 15501 80 120 
"sue" 15596 80 120 
"mary" 14998 90 154 
"mary" 15165 91 179 
"mary" 15280 91 156 
"mary" 15386 81 154 
"mary" 15952 77 133 
"mary" 15952 80 144 
"mary" 16390 91 159 
end 

Некоторые люди имеют несколько чтений на один день, например, см Сью на 31 марта 1999 года я хочу, чтобы выбрать самый низкий чтения в день.

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

*make flag for repeat observations on same day 

sort id eventdate 
by id: gen flag =1 if eventdate==eventdate[_n-1] 
by id: gen flag2=1 if eventdate==eventdate[_n+1] 
by id: gen flag3 =1 if flag==1 | flag2==1 
drop flag flag2 

* group repeat observations together 

egen group = group(id flag3 eventdate) 

* find lowest `sys_bp_copy` value per group 

bys group (eventdate flag3): egen low_sys=min(sys_bp_copy) 

*remove the observations where the lowest value of `sys_bp`_copy doesn't exist 

bys group: gen remove =1 if low_sys!=sys_bp_copy 
drop if remove==1 & group !=. 

**** Проблемы с этим и где я хотел помочь ** **

Проблема с выше подхода состоит в том, что Сью, два из ее повторных измерений имеют один и тот же Валя из sys_bp_copy. Поэтому мой подход выше меня оставляет мне несколько показаний.

В этом случае я хотел бы обратиться к dia_sys_copy и выбрать самое низкое значение там, чтобы помочь мне выбрать одну строку на человека при наличии нескольких показаний. Код для этого ниже - но должен быть более простой способ сделать это?

drop flag3 remove group 

sort id eventdate 
by id: gen flag =1 if eventdate==eventdate[_n-1] 
by id: gen flag2=1 if eventdate==eventdate[_n+1] 
by id: gen flag3 =1 if flag==1 | flag2==1 

egen group = group(id flag3 eventdate) 
bys group (eventdate flag3): egen low_dia=min(dia_bp_copy) 

bys group: gen remove =1 if low_dia!=dia_bp_copy 
drop if remove==1 & group !=. 
+0

ОК, я отредактирую, чтобы сделать больше сукцина. подожди. – user2363642

ответ

2

Низкое систолическое давление для пациента в определенный день легко определить: вы просто сортируете и ищите самое низкое значение в каждом блоке наблюдений.

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

clear 
input str4 id int eventdate byte dia_bp_copy int sys_bp_copy 
"pat" 15698 100 140 
"pat" 16183 80 120 
"pat" 19226 98 155 
"pat" 19375 80 130 
"sue" 14296 80 120 
"sue" 14334 88 127 
"sue" 14334 96 158 
"sue" 14334 84 136 
"sue" 14403 86 124 
"sue" 14403 88 134 
"sue" 14403 90 156 
"sue" 14403 86 134 
"sue" 14403 90 124 
"sue" 14431 80 120 
"sue" 14431 80 140 
"sue" 14431 80 130 
"sue" 15456 80 130 
"sue" 15501 80 120 
"sue" 15596 80 120 
"mary" 14998 90 154 
"mary" 15165 91 179 
"mary" 15280 91 156 
"mary" 15386 81 154 
"mary" 15952 77 133 
"mary" 15952 80 144 
"mary" 16390 91 159 
end 

bysort id eventdate (sys) : gen lowest = sys[1] 

bysort id eventdate (sys dia) : gen lowest_2 = sys[1] 

egen tag = tag(id eventdate) 

count if lowest != lowest_2 

list id event dia sys lowest* if tag, sepby(id) 

    +-----------------------------------------------------------+ 
    | id eventd~e dia_bp~y sys_bp~y lowest lowest_2 | 
    |-----------------------------------------------------------| 
    1. | mary  14998   90  154  154  154 | 
    2. | mary  15165   91  179  179  179 | 
    3. | mary  15280   91  156  156  156 | 
    4. | mary  15386   81  154  154  154 | 
    5. | mary  15952   77  133  133  133 | 
    7. | mary  16390   91  159  159  159 | 
    |-----------------------------------------------------------| 
    8. | pat  15698  100  140  140  140 | 
    9. | pat  16183   80  120  120  120 | 
10. | pat  19226   98  155  155  155 | 
11. | pat  19375   80  130  130  130 | 
    |-----------------------------------------------------------| 
12. | sue  14296   80  120  120  120 | 
13. | sue  14334   88  127  127  127 | 
16. | sue  14403   86  124  124  124 | 
21. | sue  14431   80  120  120  120 | 
24. | sue  15456   80  130  130  130 | 
25. | sue  15501   80  120  120  120 | 
26. | sue  15596   80  120  120  120 | 
    +-----------------------------------------------------------+ 

egen очень полезно (раскрытие различных интересов там), но основная идея здесь заключается в том, что только by: определяет группу наблюдений, и вы можете сделать это в течение двух или более переменных, а не только один - и также контролируйте порядок сортировки. Как бы то ни было, около половины egen построено на таких идеях, но это может быть проще всего и лучше всего использовать их напрямую.

+0

Я полностью сделал гору из мухи. Спасибо за это и терпеливо объясняю команду egen. – user2363642

+0

Не волнуйтесь: иногда требуется 20 лет, чтобы увидеть решение через 20 минут, а не 20 часов ... См. Например. HTTP: // WWW.stata-journal.com/sjpdf.html?articlenum=pr0004 –

+0

Большое спасибо за ссылку на статью. # romewasn'tbuiltinaday :) – user2363642

2

Если я понимаю:

Создать идентификатор же идентификатор и ту же дату

egen temp_group = group(id eventdate) 

Найти первое вхождение на основе самой низкой sys_bp_copy, а затем низкий dia_bp_copy

bys temp_group (sys_bp_copy dia_bp_copy): gen temp_first = _n 
keep if temp_first == 1 
drop temp* 

или в 1 строке по предложению:

bys id eventdate (sys_bp_copy dia_bp_copy): keep if _n==1 
+2

Та же основная идея, что и моя (upvote!), Но переменная, созданная 'group()', лишняя. Если вы перепишете свою вторую команду как 'bysort id eventdate (sys dia)', то у нас будет такое же решение. Опять же, переменная 'temp_first' является излишней: вы можете« сохранить »первое наблюдение в рамках' by: '. –

+0

Благодарим вас за помощь здесь! – user2363642

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