此问题与Identify unique levels of categorical variable
有关我有一个数据集如下:
clear
input int(id date) str8 druggroup
1001 18401 "loop"
1001 18414 "loop"
1001 18428 "loop"
1001 18462 "loop"
1001 18428 "CCB"
1001 18462 "arb"
1002 18401 "arb"
1002 18473 "arb"
1002 18414 "thiazide"
1002 18428 "thiazide"
1002 18428 "CCB"
1002 18466 "CCB"
end
format %td date
我想创建一个新变量,其中包含最早的日期,我有证据表明每个id使用三个独立的药物组。
定义"三个证据的规则"是因为我想要再次出现药物组1的重复证据,此外还有药物组2和3的出现。换句话说,药物组1显然会在第一行出现一次,但我希望它再次发生。 Druggroups 2和3不需要重复出现,但它们都必须发生。
到目前为止我写的代码没有考虑到第一次出现的药物需要在第一次出现后再次出现才算作重复使用的证据。
这是我到目前为止的代码:
bysort id druggroup (date) : gen firstdate = date[1]
format firstdate %td
list
egen group = group(id firstdate druggroup)
bysort id (group date druggroup): gen count_1 = sum(group != group[_n-1])
replace firstdate=date[2] if count_1==1
list
by id: gen start_date=firstdate if count_1==3
format start_date %td
by id : egen start_d=max(start_date)
format start_d %td
list
这是我真正想要的:
clear
input int(id date) str8 druggroup float(firstdate group count_1 start_date start_d)
1001 18401 "loop" 18414 1 1 . 18462
1001 18414 "loop" 18414 1 1 . 18462
1001 18428 "CCB" 18428 2 2 . 18462
1001 18428 "loop" 18414 1 1 . 18462
1001 18462 "loop" 18414 1 1 . 18462
1001 18462 "arb" 18462 3 3 18462 18462
1002 18401 "arb" 18414 4 1 . 18473
1002 18414 "thiazide" 18414 5 2 . 18473
1002 18428 "CCB" 18428 6 3 . 18473
1002 18428 "thiazide" 18414 5 2 . 18473
1002 18466 "CCB" 18428 6 3 . 18473
1002 18473 "arb" 18414 4 1 18473 18473
end
format %td date
format %td firstdate
format %td start_date
format %td start_d
答案 0 :(得分:0)
这里的解决方案我觉得很好,因为它基于素数。但只有每个身份证有3种药物才有效。
bysort id druggroup (date) : gen firstdate = date[1]
egen group = group(id firstdate druggroup)
bysort id (group date druggroup): gen count = sum(group != group[_n-1])
sort id date
replace count = 5 if count == 3
replace count = 3 if count == 2
replace count = 2 if count == 1
我们将在每个日期计算累积产品(但是第一个日期,因为您不想计算第一个药物出现时间)。一旦这个产品是2 * 3 * 5的倍数,即15,这意味着已经服用了三种药物(加上第一种药物)
bysort id (date) : gen temp_prod = sum(ln(count)) if _n !=1
by id (date) : replace temp_prod = int(exp(temp_prod))
gen temp_mod = mod(temp_prod, 15)
bysort id (temp_mod) : gen start_date = date if _n == 1
sort id date
drop temp* first count
format %td start_date
答案 1 :(得分:0)
我们必须找到每种药物和每位患者的第一次约会,然后是第一次使用的药物的第二次约会。如果在第一天分配两种或更多种药物可能会有问题。暗示似乎并没有发生这种情况。
我不得不说,我通常需要多次尝试才能使命令完全适合这类问题。
此处使用的某些<img id="avatar" width="100" height="100" src="/image/avatar.jpg"/>
技术在http://www.stata-journal.com/sjpdf.html?articlenum=dm0055
egen
。
答案 2 :(得分:0)
我想我已经提出了一种更为直接的方式(总是很乐意纠正!)。但是我的方法中有一个小问题,我将非常感谢你的帮助。
bysort id druggroup (date) : gen firstdate = date[1]
format firstdate %td
egen group2 = group(id firstdate druggroup)
bysort id (group2 druggroup date): gen count_1 = sum(group2 != group2[_n-1])
by id: replace firstdate=date[2] if count_1==1 //be careful of ordering here
by id : egen s_d=max(firstdate)
format s_d %td
问题是GROUP代码。如果我在同一天有两个药物组,那么这些组的顺序就会变得混乱,因为stata按字母顺序排序。我不想按字母顺序排列 - 我希望stata保留我为排序安排数据的顺序。当我在同一天有两个药物组时,有没有办法告诉小组按字母顺序自动停止?
修改
我还没弄清楚如何在这里打破关系。这是我的解决方法,并不完美但处理'egen(group)'自动按字母顺序排列同一日期发生的药物组的问题。
在我的解决方法中,我服用了同一天发生的第二种药物并将其日期更改为日期+ 1。这允许我保留顺序,似乎仍然可以获得正确的结果。
这里的目标是创建一个新的日期变量;该日期应该是我在第一种药物发生后有3种药物证据的最早日期(因此需要第一种药物在首次发生后再次发生,但另外两种药物会发生)。
下面的代码和新的样本数据。
clear
input int(id date) str8 druggroup byte tag
1001 18401 "loop" 1
1001 18414 "loop" 2
1001 18428 "loop" 2
1001 18428 "CCB" 2
1001 18462 "loop" 2
1001 18462 "arb" 2
2002 18401 "thiazide" 1
2002 18401 "arb" 2
2002 18428 "CCB" 2
2002 18428 "thiazide" 2
2002 18466 "CCB" 2
2002 18473 "arb" 2
3003 18401 "BB" 1
3003 18401 "arb" 2
3003 18428 "BB" 2
3003 18428 "CCB" 2
3003 18466 "CCB" 2
3003 18473 "arb" 2
end
format %td date
* make date_copy var
gen date_copy= date
replace date_copy=date+1 if date==date[_n-1] & tag[_n-1]==1
format date_copy %td
bysort id druggroup (date_copy) : gen firstdate = date_copy[1]
format firstdate %td
list
sort id date tag
list
*获取群组和新计数
egen group = group(id firstdate druggroup)
bysort id (group date druggroup): gen count_1 = sum(group != group[_n-1])
list
by id : replace firstdate=date[2] if count_1==1
list
by id : egen s_d=max(firstdate)
format s_d %td
list