以前的观察

时间:2017-05-18 08:49:15

标签: foreach stata missing-data

我需要你的帮助以解决以下问题。 我的数据是

ack            det                     uniquenr

02mar2015 10:30:19  27feb2015 17:03:25 1

09mar2015 11:56:44  07mar2015 22:05:52 2

16mar2015 09:59:51  09mar2015 11:08:36 2

16mar2015 09:59:51  09mar2015 11:08:36 2

16mar2015 09:59:51  09mar2015 11:08:36 2

16mar2015 09:59:51  09mar2015 11:08:36 2

24feb2015 15:03:00  21feb2015 10:23:00 3

ackdet是日期时间。 det必须与具有相同唯一编号的ack之后的最早匹配。如上例所示,09mar2015的det错误。我希望结果如下:

ack            det                     uniquenr

02mar2015 10:30:19  27feb2015 17:03:25 1

09mar2015 11:56:44  07mar2015 22:05:52 2

09mar2015 11:56:44  09mar2015 11:08:36 2

09mar2015 11:56:44  09mar2015 11:08:36 2

09mar2015 11:56:44  09mar2015 11:08:36 2

09mar2015 11:56:44  09mar2015 11:08:36 2

24feb2015 15:03:00  21feb2015 10:23:00 3

我尝试过以下代码:

sort uniquenr det
bysort uniquenr (det): gen v1= (ack[_n-1]-det)/(1000*60*60)
gen v2= (ack-det)/(1000*60*60)
gen  bedrenabo=1 if v1<v2
order bedrenabo v1 v2
replace bedrenabo=0 if v1==v2
replace bedrenabo=0 if v1<0
replace bedrenabo=0 if v1>v2
gen double newack1=ack[_n-1] if bedrenabo==1
format newack %tc
order Handling newack1 ack det tra
sort uniquenr det
replace ack=newack1 if newack1!=. 

我的结果是

    ack            det                     uniquenr newack 

02mar2015 10:30:19  27feb2015 17:03:25 1

09mar2015 11:56:44  07mar2015 22:05:52 2

16mar2015 09:59:51  09mar2015 11:08:36 2 09mar2015 11:56:44

16mar2015 09:59:51  09mar2015 11:08:36 2

16mar2015 09:59:51  09mar2015 11:08:36 2

16mar2015 09:59:51  09mar2015 11:08:36 2

24feb2015 15:03:00  21feb2015 10:23:00 3

问题似乎出现了,因为数据中存在重复项,我使用[_n-1]。最佳解决方案是使用replace命令,对于具有相同detuniquenr的所有观察,使用已知newack替换所有缺失值 - 如果有{{}} {1}}。命令newack每次都会给出不同的更改量。

我还不熟悉bysort uniquenr det : replace nyack1 = newack1[_n-1] if missing(newack1)循环,但如果是这样的话,我愿意接受它。

1 个答案:

答案 0 :(得分:1)

好的,好吧,假设我理解这个问题,这是一个可能的解决方案。

请注意,我已经修改了原始示例以使其更通用(否则一个简单的egen会做,但在我看来,这不是你想要的。)

// Input the data
// @Msh, generally it is helpful if you provide somthing like this with your Q.
clear
input str18 ackstr str18 detstr uniquenr
"02mar2015 10:30:19" "27feb2015 17:03:25" 1
"09mar2015 11:56:44" "07mar2015 22:05:52" 2
"16mar2015 09:59:51" "09mar2015 11:08:36" 2
"16mar2015 09:59:51" "09mar2015 11:08:36" 2
"16mar2015 09:59:51" "09mar2015 11:08:36" 2
"16mar2015 09:59:51" "09mar2015 11:08:36" 2
"24feb2015 15:03:00" "21feb2015 10:23:00" 3
end

gen double ack = clock(ackstr, "DMYhms")
gen double det = clock(detstr, "DMYhms")
format ack det %tc
drop *str

// I will modify the original data to make it more general
replace ack = tc(08mar2015 00:00:00) in 5

// Add row identifiers
gen id = _n

// Create all possible combinations of ack and det withing the same uniquenr
preserve
    keep uniquenr ack
    rename ack new=
    tempfile ack
    save `ack'
restore
joinby uniquenr using `ack'

// Drop ack that are smaller than det
drop if newack < det

// Match the smallest ack to a given det
ds newack id, not
collapse (min) newack (last) `r(varlist)', by(id)

您也可以使用循环执行此操作,例如以这种方式:

// Add row numbers
gen id = _n

// Prepare newack
gen double newack = .
format newack %tc

// Ensure the data is sorted
sort uniquenr ack

// Compute block boundaries
gen row = _n
by uniquenr: gen min = row[1]
by uniquenr: gen max = row[_N]

// Compute new ack
forvalues i = 1/`c(N)' {
    forvalues j = `=min[`i']'/`=max[`i']' {
        if `=ack[`j']' >= `=det[`i']' {
            replace newack = ack[`j'] in `i'
            continue, break
        }
    }
}

// Revert the sorting
sort id

如果你有一个大型数据集,那么重写mata中的循环可能是有意义的,这应该更快。