将原始数据转换为长格式

Converting raw data into long format

我正在导入既不长也不宽的数据:

clear

input str1 id purchased sold
A 2017 .
B . .
C 2016 2019
C 2018 .
D 2018 2019
D 2018 .
end

我的目标是获取以下长格式的数据,反映每年的计数:

Identifier Year Inventory
     A     2016     0
     A     2017     1
     A     2018     1
     A     2019     1
     B     2016     0
     B     2017     0
     B     2018     0
     B     2019     0
     C     2016     1
     C     2017     1
     C     2018     2
     C     2019     1
     D     2016     0
     D     2017     0
     D     2018     2
     D     2019     1

我最初的方法是首先将其转换为宽格式,即每个标识符只有一行,并在 2016-2018 年之间添加列。然后将此格式转换为所需的长格式。但是,这似乎效率低下。

因为我有一个更大的数据集,是否有任何更短、更有效的方法来做到这一点?

这需要几个小技巧。最关键的是 reshape longfillin。 库存本质上是 运行 采购减去销售的总和。

clear
input str1 Identifier  Purchased  Sold 
A   2017    .
B   .   .
C   2016    2019
C   2018    .
D   2018    2019
D   2018    .
end 

generate long id = _n 
rename (Purchased Sold) year= 
reshape long year, i(id) j(Event) string 
drop id 

fillin Id year 
drop _fillin 
drop if missing(year) 

bysort Id (year Event) : generate inventory = sum((Event == "Purchased") - (Event == "Sold")) 
drop Event 
bysort Id year : keep if _n == _N 
list, sepby(Id) 

     +----------------------------+
     | Identi~r   year   invent~y |
     |----------------------------|
  1. |        A   2016          0 |
  2. |        A   2017          1 |
  3. |        A   2018          1 |
  4. |        A   2019          1 |
     |----------------------------|
  5. |        B   2016          0 |
  6. |        B   2017          0 |
  7. |        B   2018          0 |
  8. |        B   2019          0 |
     |----------------------------|
  9. |        C   2016          1 |
 10. |        C   2017          1 |
 11. |        C   2018          2 |
 12. |        C   2019          1 |
     |----------------------------|
 13. |        D   2016          0 |
 14. |        D   2017          0 |
 15. |        D   2018          2 |
 16. |        D   2019          1 |
     +----------------------------+