我希望能够将差异和百分比更改添加到数据框中的每个列。
我能够融化数据并执行计算,但我无法弄清楚如何将它重新组合或重塑。我也怀疑这可以通过 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
(我不知道为什么Delt会自己创建列名,但我放弃了它)
现在,我可以cast(longley.m, Year ~ variable)
回到原始数据集,但我希望能够在不同的列中对每个变量进行差异和百分比更改,而无需对每个变量手动执行计算,然后将它重新绑定在一起。我非常有信心我已经尝试了各种演员阵容无济于事......
更新 Joran解决了Delt列命名问题:用as.vector强制它!
答案 0 :(得分:2)
使用Delt
时出现奇怪列名的原因是返回矩阵而不是向量。用as.vector
强迫它解决了这个谜。
然而,我怀疑你这太复杂了。您是否有理由不能简单地按年度对数据框进行排序,然后将diff
和Delt
应用于每个列,相应地重命名列,然后cbind
将它们组合在一起?< / p>
一些入门代码:
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))])
答案 1 :(得分:2)
我可能更像@joran。
但是如果你想沿着你所在的道路前进,你可以使用基地R的reshape()
来完成旅程:
# 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")
答案 2 :(得分: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) )