3

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

我能够尽可能地融合数据并执行计算,但我不知道如何将它重新组合在一起。我也有一个偷偷摸摸的怀疑,这很容易用plyr完成,但是返回的 n-1 行diff()给我带来了问题。

使用包含的数据集:

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

(我不知道为什么 Delt 使用它自己的列名,但我已经放弃了)

现在,我可以cast(longley.m, Year ~ variable)返回原始数据集,但我希望能够在不同列中为每个变量获得差异和百分比变化,而无需对每个变量手动执行计算,然后将其重新绑定在一起。我很有信心我已经尝试了各种演员阵容,但无济于事......

更新: Joran 解决了 Delt 列命名问题:用 as.vector 强制它!

4

3 回答 3

2

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

但是,我怀疑你把这件事弄得太复杂了。您是否有理由不能简单地按年份对数据框进行排序,然后将diffandDelt应用于每一列,适当地重命名这些列,然后将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))])
于 2012-01-01T01:49:41.217 回答
2

我可能会更像@joran。

但是,如果您想沿着您之前的路径继续前进,您可以使用reshape()from base 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")
于 2012-01-01T01:56:18.297 回答
0

我认为融化然后在指标类别内处理的策略是不必要的复杂。如果您想要一个在开始时添加一行 NA 的数据框,以便它与行号匹配,那么有两种选择建议自己作为一个衬垫:

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

或者,如果您知道所有条目都是数字的(如使用数字函数所建议的那样)并且因此可以使用,apply那么这种方法甚至更简单:

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

如果你想要这些和 Delt 结果一起:

cbind(apply(longley,2, FUN=function(x) c(NA, diff(x))), 
      apply(longley,2, Delt) )
于 2012-01-01T15:40:26.763 回答