2017-05-07 74 views
4

我有长格式的Compustat数据,我通过spread(来自tidyr包)转换为宽格式。R - 从长到宽,再回到相同的长格式

然后我做了一些计算,之后我想再次将数据帧恢复为长格式。是否有任何一种“内存”功能,以便我的新的长数据框与旧的数据框完全相同(相同的顺序)。

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

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

长格式“原始”(称为“测试”):

`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 

正如你可以看到有很多多个NAS现在(因为它们创建打算形式长宽)和NA省略ISN是一种选择,因为所有的NA都被省略(不仅是新创建的)。 因此,当我从宽格式再次返回到长格式时,我想要得到旧的(18行)长格式数据帧,而不是我得到的(24行和“新”NAs)。

我希望我的问题现在已经被理解了。你可以看到我没有设法在第一列中获得kypermno,在第二列中获得fyyyyq(在返回长格式之后),但是我认为它不会影响上述问题。

+2

请提供可重复的问题/例如,或给予什么样的问题的数据集看起来有些迹象喜欢和你期望的样子。仔细阅读本文,以获取有关可重现实例的灵感。 http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – Drj

回答

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) 

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

+0

我处理了这个问题,用一封信替换原来的NAs,当我从宽到长回到我可以省略NAs,并用“新”长格式的NAs再次替换该字母。我不得不采用宽格式,因为我必须计算每种库存随时间的60个季度ROE标准差(至少有12次未丢失观察值),而且我没有看到用长格式。 – kayB