如何将Stata中的长数据转换为宽数据?

如何将Stata中的长数据转换为宽数据?,stata,reshape,Stata,Reshape,我有以下数据: id test test_date value 1 A 02/06/2014 12:26 11 1 B 02/06/2014 12:26 23 1 C 02/06/2014 13:17 43 1 D 02/06/2014 13:17 65 1 E 02/06/2014 13:17 34 1 F 02/06/2014 13:17 64 1 A 05/06/2014 15:14

我有以下数据:

id  test    test_date   value
1   A   02/06/2014 12:26    11
1   B   02/06/2014 12:26    23
1   C   02/06/2014 13:17    43
1   D   02/06/2014 13:17    65
1   E   02/06/2014 13:17    34
1   F   02/06/2014 13:17    64
1   A   05/06/2014 15:14    234
1   B   05/06/2014 15:14    646
1   C   05/06/2014 16:50    44
1   E   05/06/2014 16:50    55
2   E   05/06/2014 16:50    443
2   F   05/06/2014 16:50    22
2   G   05/06/2014 16:59    445
2   B   05/06/2014 20:03    66
2   C   05/06/2014 20:03    77
2   D   05/06/2014 20:03    88
2   E   05/06/2014 20:03    44
2   F   05/06/2014 20:19    33
2   G   05/06/2014 20:19    22
我想将此数据转换为以下宽格式:

id    date              A   B   C   D   E   F   G
1   02/06/2014 12:26    11  23  43  65  34  64  .
1   05/06/2014 15:14    234 646 44  .   55  .   .
2   05/06/2014 16:50    .   .   .   .   443 22  445
2   05/06/2014 20:03    .   66  77  88  44  33  22

我正在Stata中使用
重塑
命令,但它没有产生所需的结果:

reshape wide test_date value, i(id) j(test) string
你知道怎么做吗

更新:
你说得对,我们需要这个missvar。我试图通过编程来创建它,但失败了。让我们说在2小时的测试日期,批次将考虑相同。我们只有7个测试(A、B、C、D、E、F、G)。首先,我试图找出时差

 bysort id: gen diff_bd = (test_date[_n] - test_date[_n-1])/(1000*60*60)    

 bysort id: generate missvar = _n if diff_bd <= 2 
bysort id:gen diff_bd=(测试日期[\n]-测试日期[\n-1])/(1000*60*60)

bysort id:generate missvar=\n如果diff\u bd命令的指定有点错误。您想重塑
。查看您想要的输出,注意观察结果由
id
test\u date
唯一标识。因此,它们应该位于
i
选项中

reshape wide value, i(id test_date) j(test) string
这会产生与您想要的非常接近的结果,您只需重命名一些变量即可获得精确的输出。具体而言:

rename test_date date
renpfix value

该命令的指定有点错误。您想重塑
。查看您想要的输出,注意观察结果由
id
test\u date
唯一标识。因此,它们应该位于
i
选项中

reshape wide value, i(id test_date) j(test) string
这会产生与您想要的非常接近的结果,您只需重命名一些变量即可获得精确的输出。具体而言:

rename test_date date
renpfix value

@jfeigenbaum给出了部分答案

我看到的问题是缺少一个标识相关子组的变量。这些亚组似乎受
test
取值
A-G
的限制。但我可能错了

我在示例数据集中包含了这个变量,并将其命名为
missvar
。我强迫这个变量进入数据集中,相信它能识别出那些对你的分析很重要的群体,尽管这些群体在你的原始帖子中是隐含的

clear
set more off

*----- example data -----

input ///
id  str1 test    str30 test_date   value missvar
1   A   "02/06/2014 12:26"    11 1
1   B   "02/06/2014 12:26"    23 1
1   C   "02/06/2014 13:17"    43 1
1   D   "02/06/2014 13:17"    65 1
1   E   "02/06/2014 13:17"    34 1
1   F   "02/06/2014 13:17"    64 1
1   A   "05/06/2014 15:14"    234 2
1   B   "05/06/2014 15:14"    646 2
1   C   "05/06/2014 16:50"    44 2
1   E   "05/06/2014 16:50"    55 2
2   E   "05/06/2014 16:50"    443 1
2   F   "05/06/2014 16:50"    22 1
2   G   "05/06/2014 16:59"    445 1
2   B   "05/06/2014 20:03"    66 2
2   C   "05/06/2014 20:03"    77 2
2   D   "05/06/2014 20:03"    88 2
2   E   "05/06/2014 20:03"    44 2
2   F   "05/06/2014 20:19"    33 2
2   G   "05/06/2014 20:19"    22 2
end

gen double tdate = clock( test_date, "DM20Yhm")
format %tc tdate

drop test_date
list, sepby(id)

*----- what you want ? -----

reshape wide value, i(id missvar tdate) j(test) string
collapse (min) tdate value?, by(id missvar)

rename value* *

list
应该有某种方法以编程方式标识组。依赖数据的原始排序顺序是一种方法,但它可能不是最安全的。这可能是唯一的办法,但只有你知道

编辑 关于您的评论和“缺失”变量,创建它的一种方法是:

// one hour is 3600000 milliseconds
bysort id (tdate): gen batch = sum(tdate - tdate[_n-1] > 7200000)
对于示例数据,这将创建一个与my
missvar
相同的
batch
变量。也可以使用时间序列运算符

让我强调,在展示示例数据时,您需要非常小心。它必须是真实的代表性的,否则您可能会得到不适合它的代码;这包括你没有注意到的可能性,因为Stata没有给出错误

例如,如果您在两小时内对相同的
id
应用了相同的
测试
,那么您将丢失此代码的信息(在
折叠中)。(在示例数据中,这不是问题。)

编辑2 针对评论中的另一个问题:

假设对人1进行新的观察,使其在两小时内接受重复测试,但在不同的时间

1   A   "02/06/2014 12:26"    11 1 // old observation
1   B   "02/06/2014 12:26"    23 1
1   A   "02/06/2014 12:35"    99 1 // new observation
1   C   "02/06/2014 13:17"    43 1
1   D   "02/06/2014 13:17"    65 1
1   E   "02/06/2014 13:17"    34 1
1   F   "02/06/2014 13:17"    64 1
1   A   "05/06/2014 15:14"    234 2
1   B   "05/06/2014 15:14"    646 2
1   C   "05/06/2014 16:50"    44 2
1   E   "05/06/2014 16:50"    55 2
测试
A
12:26
12:35
应用<代码>重塑
对此没有问题,但是
折叠
将丢弃信息,因为它在
id missvar
组中取最小值;请注意,对于变量
valueA
,新信息(99)将丢失(所有其他变量也会丢失,但您明确表示要放弃该信息)。在
重塑
之后但在
折叠
之前,您会得到:

. list, sepby(id)

     +--------------------------------------------------------------------------------------------------+
     | id   missvar                tdate   valueA   valueB   valueC   valueD   valueE   valueF   valueG |
     |--------------------------------------------------------------------------------------------------|
  1. |  1         1   02jun2014 12:26:00       11       23        .        .        .        .        . |
  2. |  1         1   02jun2014 12:35:00       99        .        .        .        .        .        . |
  3. |  1         1   02jun2014 13:17:00        .        .       43       65       34       64        . |
  4. |  1         2   05jun2014 15:14:00      234      646        .        .        .        .        . |
  5. |  1         2   05jun2014 16:50:00        .        .       44        .       55        .        . |
     |--------------------------------------------------------------------------------------------------|
  6. |  2         1   05jun2014 16:50:00        .        .        .        .      443       22        . |
  7. |  2         1   05jun2014 16:59:00        .        .        .        .        .        .      445 |
  8. |  2         2   05jun2014 20:03:00        .       66       77       88       44        .        . |
  9. |  2         2   05jun2014 20:19:00        .        .        .        .        .       33       22 |
     +--------------------------------------------------------------------------------------------------+
运行完整的代码证实了我们刚才所说的:

. list, sepby(id)

     +--------------------------------------------------------------------------+
     | id   missvar                tdate     A     B    C    D     E    F     G |
     |--------------------------------------------------------------------------|
  1. |  1         1   02jun2014 12:26:00    11    23   43   65    34   64     . |
  2. |  1         2   05jun2014 15:14:00   234   646   44    .    55    .     . |
     |--------------------------------------------------------------------------|
  3. |  2         1   05jun2014 16:50:00     .     .    .    .   443   22   445 |
  4. |  2         2   05jun2014 20:03:00     .    66   77   88    44   33    22 |
     +--------------------------------------------------------------------------+
现在假设对人1进行新的观察,使其在两小时内接受重复测试,但同时接受

1   A   "02/06/2014 12:26"    11 1 // old observation
1   B   "02/06/2014 12:26"    23 1
1   A   "02/06/2014 12:26"    99 1 // new observation
1   C   "02/06/2014 13:17"    43 1
1   D   "02/06/2014 13:17"    65 1
1   E   "02/06/2014 13:17"    34 1
1   F   "02/06/2014 13:17"    64 1
1   A   "05/06/2014 15:14"    234 2
1   B   "05/06/2014 15:14"    646 2
1   C   "05/06/2014 16:50"    44 2
1   E   "05/06/2014 16:50"    55 2
然后,
重塑
将不起作用。斯塔塔抱怨说:

id missvar tdate内的变量测试值不唯一

而且有理由。在发出故障信号时,错误是显而易见的。(如果不清楚,请返回
帮助重塑
并进行一些练习。)鉴于命令的功能,该请求毫无意义


最后,请注意,检查某些东西是否有效相对容易:试试看!在这种情况下,所需要做的只是稍微修改一下示例数据。如有必要,请返回帮助文件和手册。

@jfeigenbaum给出了部分答案

我看到的问题是缺少一个标识相关子组的变量。这些亚组似乎受
test
取值
A-G
的限制。但我可能错了

我在示例数据集中包含了这个变量,并将其命名为
missvar
。我强迫这个变量进入数据集中,相信它能识别出那些对你的分析很重要的群体,尽管这些群体在你的原始帖子中是隐含的

clear
set more off

*----- example data -----

input ///
id  str1 test    str30 test_date   value missvar
1   A   "02/06/2014 12:26"    11 1
1   B   "02/06/2014 12:26"    23 1
1   C   "02/06/2014 13:17"    43 1
1   D   "02/06/2014 13:17"    65 1
1   E   "02/06/2014 13:17"    34 1
1   F   "02/06/2014 13:17"    64 1
1   A   "05/06/2014 15:14"    234 2
1   B   "05/06/2014 15:14"    646 2
1   C   "05/06/2014 16:50"    44 2
1   E   "05/06/2014 16:50"    55 2
2   E   "05/06/2014 16:50"    443 1
2   F   "05/06/2014 16:50"    22 1
2   G   "05/06/2014 16:59"    445 1
2   B   "05/06/2014 20:03"    66 2
2   C   "05/06/2014 20:03"    77 2
2   D   "05/06/2014 20:03"    88 2
2   E   "05/06/2014 20:03"    44 2
2   F   "05/06/2014 20:19"    33 2
2   G   "05/06/2014 20:19"    22 2
end

gen double tdate = clock( test_date, "DM20Yhm")
format %tc tdate

drop test_date
list, sepby(id)

*----- what you want ? -----

reshape wide value, i(id missvar tdate) j(test) string
collapse (min) tdate value?, by(id missvar)

rename value* *

list
应该有某种方法以编程方式标识组。依赖数据的原始排序顺序是一种方法,但它可能不是最安全的。这可能是唯一的办法,但只有你知道

编辑 关于您的评论和“缺失”变量,创建它的一种方法是:

// one hour is 3600000 milliseconds
bysort id (tdate): gen batch = sum(tdate - tdate[_n-1] > 7200000)
对于示例数据,这将创建一个与my
missvar
相同的
batch
变量。也可以使用时间序列运算符

让我强调,在展示示例数据时,您需要非常小心。它必须是真实的代表性的,否则您可能会得到不适合它的代码;这包括你没有注意到的可能性,因为Stata没有给出错误

例如,如果您在两小时内对相同的
id
应用了相同的
测试
,那么您将丢失此代码的信息(在
折叠中)。(这不是问题