R - 从长到宽再回到相同的长格式

R - From long to wide and back to the same long format

我有长格式的 Compustat 数据,我通过 spread(来自 tidyr 包)将其转换为宽格式。

然后我做了一些计算,之后我想再次将数据帧恢复为长格式。是否有任何类型的 "memory" 函数,以便我的新长数据帧与旧数据帧完全相同(相同顺序)。

问题是有很多NA,每只股票的数据都是从股票首次上市开始到退市后或样本结束时结束。我的样本从 1960 年到 2015 年(每季度)。当然,并非所有股票都有所有日期的数据,但当我从宽格式返回到长格式时,每只股票都会获得从 1960.1 到 2015.4 的所有日期。这个长格式数据帧是我正在构建的乐谱的一部分,我必须将它与其他长格式数据帧进行比较(它们都具有相同的 kypermno 和日期顺序),因此我需要将宽数据帧转换回与新值完全相同的原始形式。

编辑:这是我的问题的一个例子:

长格式'original'(称为'test'):

    `kypermno fyyyyq ROE_Q
      <int>  <int> <dbl>
1      1001   1985  0.56
2      1001   1986  0.43
3      1001   1987  0.78
4      1001   1988    NA
5      1001   1989  0.34
6      1001   1990  0.76
7      1002   1980  0.12
8      1002   1981  0.67
9      1002   1982  0.12
10     1002   1983  0.56
11     1002   1984    NA
12     1002   1985  0.91
13     1002   1986  0.45
14     1002   1987  0.23
15     1002   1988  0.54
16     1002   1989  0.14
17     1002   1990  0.19
18     1002   1991  0.27`

我用下面的代码把它放在宽格式中:

dat_wide <- spread(test, kypermno, ROE_Q)

现在在宽格式中看起来像这样:

 fyyyyq `1001` `1002`
*   <int>  <dbl>  <dbl>
1    1980     NA   0.12
2    1981     NA   0.67
3    1982     NA   0.12
4    1983     NA   0.56
5    1984     NA     NA
6    1985   0.56   0.91
7    1986   0.43   0.45
8    1987   0.78   0.23
9    1988     NA   0.54
10   1989   0.34   0.14
11   1990   0.76   0.19
12   1991     NA   0.27

当我把它放回长格式时,它变成了这样:

dat_long <- gather(dat_wide, key = 'fyyyyq', value = 'ROE_Q', -kypermno)

fyyyyq kypermno ROE_Q
    <int>    <chr> <dbl>
1    1980     1001    NA
2    1981     1001    NA
3    1982     1001    NA
4    1983     1001    NA
5    1984     1001    NA
6    1985     1001  0.56
7    1986     1001  0.43
8    1987     1001  0.78
9    1988     1001    NA
10   1989     1001  0.34
11   1990     1001  0.76
12   1991     1001    NA
13   1980     1002  0.12
14   1981     1002  0.67
15   1982     1002  0.12
16   1983     1002  0.56
17   1984     1002    NA
18   1985     1002  0.91
19   1986     1002  0.45
20   1987     1002  0.23
21   1988     1002  0.54
22   1989     1002  0.14
23   1990     1002  0.19
24   1991     1002  0.27

如您所见,现在有更多的 NA(因为它们是从长到宽创建的)并且 NA 省略不是一个选项,因为这样所有的 NA 都被省略了(不仅是新创建的 NA ). 因此,当我再次从宽格式返回到长格式时,我想获得旧的(18 行长)长格式数据帧,而不是我得到的数据帧(有 24 行和 "new" NA)。

我希望我的问题现在可以理解了。

PS:如您所见,我没有设法在第一列中获得 kypermno,在第二列中获得 fyyyyq(在返回到长格式之后),但我认为这不会影响以上问题。

有一个 fill= 选项允许您选择要用于 "fill" 间隙的值。可悲的是,它也取代了原来的 NA,所以它没用。

这是一个不优雅的解决方案,使用原始测试数据来消除最初不存在的案例。

注意:我必须稍微修改您的代码才能使其正常工作。

test <- read.table(text = 
'ID kypermno fyyyyq ROE_Q
1      1001   1985  0.56
2      1001   1986  0.43
3      1001   1987  0.78
4      1001   1988    NA
5      1001   1989  0.34
6      1001   1990  0.76
7      1002   1980  0.12
8      1002   1981  0.67
9      1002   1982  0.12
10     1002   1983  0.56
11     1002   1984    NA
12     1002   1985  0.91
13     1002   1986  0.45
14     1002   1987  0.23
15     1002   1988  0.54
16     1002   1989  0.14
17     1002   1990  0.19
18     1002   1991  0.27',
header = TRUE)
test <- test[,-1]

library(tidyr)
dat_wide <- spread(test, kypermno, ROE_Q)
dat_wide

dat_long <- gather(dat_wide, key = 'kypermno', value = ROE_Q, -fyyyyq)
dat_long


# Keep only the original data
dat_long[ paste(dat_long[,2], dat_long[,1]) %in% paste(test[,1], test[,2]),]

# Alternative (shorter and probably better)
merge(test[,1:2], dat_long, all.x=TRUE)

但也许你应该问问自己是否真的有必要将你的数据转换成宽格式...