我有长格式的Compustat数据,我通过spread
(来自tidyr
包)转换为宽格式。
然后我做了一些计算,然后我想再次将数据帧恢复为长格式。是否存在任何类型的“记忆”功能,因此我的新长数据帧与旧数据帧的方式完全相同(相同的顺序)。
问题是有很多NA
个,每个股票的数据在股票首次上市时开始,在退市后或在样本结束时结束。我的样本从1960年到2015年(季刊)。当然并非所有股票都有所有日期的数据,但是当我从宽幅格式回到长格式时,每只股票都会从1960.1到2015.4获得所有日期。这个长格式数据框是我正在构建的分数的一部分,我必须将它与其他长格式数据帧进行比较(所有这些数据帧都由kypermno和date具有相同的顺序),因为我需要将宽数据帧转换回确切的原始形式与新值。
编辑:这是我的问题的一个例子:
长格式'原创'(称为'测试'):
`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都被省略(不仅是新创建的)。 所以当我再次从宽格式再到长格式时,我想得到旧的(18行长)格式数据帧,而不是我得到的数据帧(有24行和“新”NAs)。
我希望我的问题现在可以理解了。
PS:正如你所看到的,我没有设法在第一列获得kypermno而在第二列获得fyyyyq(在回到长格式之后),但我认为它不会影响上面的问题。答案 0 :(得分:1)
有一个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)
但也许您应该问自己是否真的有必要以宽幅格式转换数据......