tidyr中的spread()函数

3
我有一个CRSP股票价格列表,如下所示。
    PERMNO  date        TICKER  RETX
1   10138   2007-01-03  TROW    0.045236
2   10138   2007-01-04  TROW    0.008743
3   10138   2007-01-05  TROW    -0.001950
4   10138   2007-01-08  TROW    0.018237
5   10138   2007-01-09  TROW    0.004051
6   10138   2007-01-10  TROW    0.005734
7   10138   2007-01-11  TROW    0.019637
8   10138   2007-01-12  TROW    0.005591
...
1   10145   2007-01-03  HON -0.003095
2   10145   2007-01-04  HON -0.000443
3   10145   2007-01-05  HON -0.009539
4   10145   2007-01-08  HON 0.006047
5   10145   2007-01-09  HON 0.007124
6   10145   2007-01-10  HON -0.006189
7   10145   2007-01-11  HON 0.016681
8   10145   2007-01-12  HON -0.003282
9   10145   2007-01-16  HON 0.001317
10  10145   2007-01-17  HON -0.001754
11  10145   2007-01-18  HON -0.010979
...

一旦我使用tidyr::spread(x,TICKER,RETX),它返回一个大部分值为NA的矩阵。是否有其他函数可以重新排列矩阵,将每个股票价格列出在一列中?或者如何通过几行代码实现?
更新: 我发现是PERMNO列引起了问题。当我去掉PERMNO列后,又出现了另一个问题:
> spread(A1[,2:4],TICKER,RETX)
Error: Duplicate identifiers for rows (129717, 143815), (129718, 143816), ...

所以,我只是随机选择了消息中提到的两行。
       PERMNO       date TICKER     RETX
129717  75104 2007-01-03    CBS 0.012172
> A1[143815,]
       PERMNO       date TICKER    RETX
143815  76226 2007-01-03    CBS 0.01347

结果表明,数据集非常脏乱,并且包含重复的系列。 更好的解决方案是使用PERMNO作为关键字。 以下是我得到的结果:

    date        10225       10516       10909       ...
1   2007-01-03  0.005738    0.003129    -0.006593   ...
2   2007-01-04  -0.011062   -0.005615   0.028761    ...
3   2007-01-05  0.000824    -0.001568   -0.022366   ...
4   2007-01-08  -0.005059   0.005027    -0.003520   ...
5   2007-01-09  0.002956    -0.024383   0.000883    ...
6   2007-01-10  -0.003301   -0.008651   -0.010587   ...
...

这真是令人沮丧,但我终于得到了一些东西。有没有办法用相应的股票代码替换数字列名?下面是一个演示:

    PERMNO  date        FO          HON        ...
1   10225   2007-01-03  0.005738    -0.003095  ...
2   10225   2007-01-04  -0.011062   -0.000443  ...
3   10225   2007-01-05  0.000824    -0.009539  ...
4   10225   2007-01-08  -0.005059   0.006047   ...
5   10225   2007-01-09  0.002956    0.007124   ...
6   10225   2007-01-10  -0.003301   -0.006189  ...
7   10225   2007-01-11  0.007925    0.016681   ...
8   10225   2007-01-12  -0.010914   -0.003282  ...

1
我猜你指的是tidyr::spread(我相应地编辑了你的问题)。你的示例很差,因为它只显示了一个RETX值,所以你的问题没有被说明---你的代码在这8行上运行得很好,没有返回任何NA。(而且它返回的是一个数据框,而不是一个矩阵。)tidyr不是内置的,但你可以看到reshape2::dcast来获得一个更灵活的spread版本。 - Gregor Thomas
然而,如果你得到了NA值,我认为你的股票有不同的permno值或不同的日期 - 可能是permno。因此,如果该列不适用于您的传播数据,请在传播之前将其删除。 - Gregor Thomas
谢谢您的建议。这是我第一次在这个网站上发布问题,我还在继续努力。 - HLD25
没问题!只需在你的问题中编辑一些数据来展示问题。你可以在这里查看更多的可重现性提示。但是请将新数据编辑到你的问题中,否则我们无法看到问题或测试解决方案。尽量找到8或10行数据,每行有两个TICKER值,4或5个日期,以展示问题。也许还可以解释一下PERMNO是什么。 - Gregor Thomas
1
那么问题就在这里了。如果你需要更多的帮助,请将代码编辑到你的问题中,而不是在评论中放置大量的代码。如果这解决了你的问题,你可能只想删除这个问题。 - Gregor Thomas
1个回答

4

如果您在某些地方有重复数据,则首先需要摆脱这些值,否则,如果使用tidyr::spread,它将用长度替换该值。无论如何,假设您已经使用unique或类似方法去掉了重复项,以下是我使用tidyr的方法,因为那是您要求的,而且tidyr相当灵巧和简洁:

 A1 <- spread(A1[, c("date", "TICKER", "RETX")], TICKER, RETX)

如果您包含PERMNO,则在TICKER的特定值没有与PERMNO匹配的值时,每行都会得到NAs。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接