如何根据日期更改字符串的顺序

How to change order of string based on dates

我收到的数据带有一个类似于以下内容的字符串变量:

var_name
25-DEC-99: A11, B14, C89; 28-FEB-94: A27, B94, C30
01-APR-11: A25, B82, C65
04-JUL-09: A21, B55, C26; 12-MAR-03: A11, B72, C68; 08-JUN-11: A62, B47, C82
12-JUN-00: A77, B19, C73; 03-JUL-12: A99, B04, C54
27-OCT-15: A22, B95, C08

等等。我的目标是将这些字符串拆分成不同的变量名。变量名称将是 v1_datev1_Av1_Bv1_Cv2_datev2_Av2_Bv2_Cv3_datev3_Av3_Bv3_C

我可以使用 split var_name, p(";"),重命名为 v1v2v3,然后再次 split 来执行此操作。但问题是我希望 v1v2v3 根据日期按时间顺序排列,而数据目前并未按这种方式排列。我怎样才能使 v1 的日期在 v2 之前并且 v2 的日期在 v3 的日期之前?例如,在第一个观察中,我希望 25-DEC-99: A11, B14, C89v2 关联,28-FEB-94: A27, B94, C30v1 关联。

一般来说,请考虑使用 dataex (SSC) 创建简单的数据示例。

您没有提供用于 split 变量的所有(并非微不足道的)代码。碰巧的是,我认为您的变量名不容易使用,所以我以自己的方式重新创建了拆分。如果您 reshape long 拆分数据,那么按日期排序很容易,但我已经拉低了反向 reshape wide,因为我怀疑长结构更容易处理。

clear
input str80 data
"25-DEC-99: A11, B14, C89; 28-FEB-94: A27, B94, C30"
"01-APR-11: A25, B82, C65"
"04-JUL-09: A21, B55, C26; 12-MAR-03: A11, B72, C68; 08-JUN-11: A62, B47, C82"
"12-JUN-00: A77, B19, C73; 03-JUL-12: A99, B04, C54"
"27-OCT-15: A22, B95, C08"
end 

split data, p(;) gen(x) 

local j = 1 
gen work = "" 
foreach x of var x* { 
    replace work = substr(`x', 1, strpos(`x', ":") - 1) 
    gen date`j' = daily(work, "DMY", 2050) 
    replace work = substr(`x', strpos(`x', ":") + 1, .) 
    split work, p(,) 
    rename (work1 work2 work3) (vA`j' vB`j' vC`j') 
    local ++j 
} 

drop work 
drop x* 
drop data 

gen id = _n 
edit 
reshape long date vA vB vC, i(id) j(which) 
drop if missing(date) 
bysort id (date): replace which = _n 
list, sepby(id) 

     +----------------------------------------+
     | id   which    date    vA     vB     vC |
     |----------------------------------------|
  1. |  1       1   12477   A27    B94    C30 |
  2. |  1       2   14603   A11    B14    C89 |
     |----------------------------------------|
  3. |  2       1   18718   A25    B82    C65 |
     |----------------------------------------|
  4. |  3       1   15776   A11    B72    C68 |
  5. |  3       2   18082   A21    B55    C26 |
  6. |  3       3   18786   A62    B47    C82 |
     |----------------------------------------|
  7. |  4       1   14773   A77    B19    C73 |
  8. |  4       2   19177   A99    B04    C54 |
     |----------------------------------------|
  9. |  5       1   20388   A22    B95    C08 |
     +----------------------------------------+

我相信以下内容会让您接近。它同时使用 splitreshape.

clear
set more off

input ///
str100 myvar
"25-DEC-99: A11, B14, C89; 28-FEB-94: A27, B94, C30"
"01-APR-11: A25, B82, C65"
"04-JUL-09: A21, B55, C26; 12-MAR-03: A11, B72, C68; 08-JUN-11: A62, B47, C82"
"12-JUN-00: A77, B19, C73; 03-JUL-12: A99, B04, C54"
"27-OCT-15: A22, B95, C08"
end

split myvar, p(;)
drop myvar

gen obs = _n
reshape long myvar, i(obs)
drop if missing(myvar)

split myvar, p(:)
drop myvar

gen myvar11 = date(myvar1, "DMY", 2020)
format %td myvar11

drop myvar1
rename (myvar11 myvar2) (mydate mycells)
order mydate, before(mycells)

bysort obs (mydate) : gen neworder = _n
drop _j

reshape wide mydate mycells, i(obs) j(neworder)

list

如果需要进一步 split,可以遍历 mycells 变量。