2012-01-01 32 views
2

我希望能够将差异和百分比变化添加到数据框中的每一列。添加数据框中每列的差异和百分比变化?

我能够融化数据和执行计算,但我无法弄清楚如何将它们重新塑造或重新塑造。我也有一个潜行的怀疑,这很容易用plyr完成,但由diff()返回n-1行给我的问题。

使用包含的数据集:

library(plyr) 
library(quantmod) 
head(longley) 

    GNP.deflator  GNP Unemployed Armed.Forces Population Year Employed 
1947   83.0 234.289  235.6  159.0 107.608 1947 60.323 
1948   88.5 259.426  232.5  145.6 108.632 1948 61.122 
1949   88.2 258.054  368.2  161.6 109.773 1949 60.171 
1950   89.5 284.599  335.1  165.0 110.929 1950 61.187 
1951   96.2 328.975  209.9  309.9 112.075 1951 63.221 
1952   98.1 346.999  193.2  359.4 113.270 1952 63.639 

longley.m <- melt(longley, id="Year") 
longley.m <- ddply(longley.m, .(variable), transform, valdiff=diff(c(NA, value)), valdelt=Delt(value)) 

head(longley.m) 

    Year  variable value valdiff Delt.1.arithmetic 
1 1947 GNP.deflator 83.0  NA    NA 
2 1948 GNP.deflator 88.5  5.5  0.066265060 
3 1949 GNP.deflator 88.2 -0.3  -0.003389831 
4 1950 GNP.deflator 89.5  1.3  0.014739229 
5 1951 GNP.deflator 96.2  6.7  0.074860335 
6 1952 GNP.deflator 98.1  1.9  0.019750520 

(我不知道为什么侧平举使得它自己的列名,但我已经放弃了对)现在

,我可以cast(longley.m, Year ~ variable)得到回到原始数据集,但是我希望能够对不同列中的每个变量进行差异和百分比更改,而无需对每个变量手动执行计算,然后将它们重新绑定到一起。我很有信心我试着投无济于事的每一个变化...

更新: Joran解决了侧平举列命名问题:与as.vector强迫它!

+0

它呢?我的问题更多的是对每一列执行相同的操作并将其放回数据框。我在那里看不到解决方案。 – Totovader 2012-01-01 01:59:20

+0

我想我不明白困难的根源。我明白我能做些什么来解决问题。 – 2012-01-01 15:42:19

回答

2

我会处理这更像@joran。

但是,如果你想沿着你的道路上继续前进,你可以使用reshape()从基础R来完成的旅程:一个指标类别中

# Your code 
library(plyr) 
library(quantmod) 
library(reshape) 
head(longley) 
longley.m <- melt(longley, id="Year") 

# My addition 
longley.m <- ddply(longley.m, .(variable), transform, 
        valdiff = diff(c(NA, value)), 
        valdelt = as.vector(Delt(value))) 
reshape(longley.m, idvar="Year", timevar="variable", direction="wide") 
+0

我认为这给了我一直在寻找的东西。重塑没有为我点击。谢谢! – Totovader 2012-01-01 02:07:48

+1

嘿。很多人都有这种“重塑”的经验。 – 2012-01-01 15:23:53

2

使用Delt时奇怪列名的原因是返回一个矩阵,而不是一个向量。强迫它与as.vector解决这个谜。

但是,我怀疑你让这太复杂了。是否有理由不能简单地按年分类数据帧,然后将diffDelt应用于每列,将这些列适当地重命名,然后cbind它们一起?

一些启动代码:

longley.o <- arrange(longley,Year) 
apply(longley.o,2,function(x){c(NA,diff(x))}) 
apply(longley.o,2,Delt) 

更完整的版本(列没有手进入):

longley.o <- arrange(longley,Year) 
valdiff <- apply(longley.o,2,function(x){c(NA,diff(x))}) 
valdelt <- apply(longley.o,2,Delt) 

colnames(valdiff) <- paste("valdiff",colnames(valdiff),sep = ".") 
colnames(valdelt) <- paste("valdelt",colnames(valdelt),sep = ".") 

out <- cbind(longley.o, 
      valdiff[,-match("Year",colnames(longley.o))], 
      valdelt[,-match("Year",colnames(longley.o))]) 
+0

谢谢你解决第一个谜!尽管我确实倾向于使事情复杂化,但在这种情况下,我感觉我至少在正确的道路上。简单地在每列上做diff和Delt的问题(在我将它融化之前)是我每年都想为每个变量指定它。我必须明确地输入解决方案中的每一列。我的实际问题在十几个不同的数据框中有20多列,所以我正在寻找简单的方法。 – Totovader 2012-01-01 01:53:04

+0

@Totovader我并不真正遵循你的推理。如果你想使用重塑,那么乔希已经覆盖了你。我上面的更新应该给出与他的回答相同的结果。 – joran 2012-01-01 02:08:38

+0

我明白你要去哪里了,现在 - 你的cbind部分的匹配部分对我来说是陌生的,所以它会是一些额外的步骤。 – Totovader 2012-01-01 02:12:34

0

我想融化的策略,然后处理是不必要的复杂。如果你想和NA的在开始时添加的行中的数据帧,因此将匹配与行号,然后两个备选方案提出自己作为一个内衬:

as.data.frame(lapply(longley, function(x) c(NA, diff(x)))) 

或者,如果你知道,所有条目均数值(如通过使用数字功能的建议),因此使用apply OK那么这种做法是更简单:

apply(longley,2, FUN=function(x) c(NA, diff(x))) 

如果你与侧平举想所有这些共同作用的结果:

cbind(apply(longley,2, FUN=function(x) c(NA, diff(x))), 
     apply(longley,2, Delt))