Добавить разницу и процентное изменение каждого столбца во фрейме данных? - PullRequest
3 голосов
/ 01 января 2012

Я хотел бы иметь возможность добавлять разницу и процентное изменение к каждому столбцу в кадре данных.

Я могу добиться того, чтобы растопить данные и выполнить вычисления, но я не могу понять, как привести их в порядок или изменить их вместе.У меня также есть подозрение, что это легко сделать с помощью 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) вернуться к исходному набору данных, ноЯ хочу иметь возможность иметь разницу и процентное изменение для каждой переменной в отдельном столбце, не выполняя вычисления вручную для каждой переменной и затем снова связывая их вместе.Я уверен, что перепробовал все варианты приведения ...

Обновление: Джоран решил проблему с именами столбцов Delt: приведите ее с помощью as.vector!

Ответы [ 3 ]

2 голосов
/ 01 января 2012

Скорее всего, я бы подошел к этому как к @ 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")
2 голосов
/ 01 января 2012

Причина использования странного имени столбца при использовании Delt заключается в том, что он возвращает матрицу, а не вектор. Принуждение к этому as.vector решает эту тайну.

Однако я подозреваю, что вы делаете это слишком сложным. Есть ли причина, по которой вы не можете просто отсортировать фрейм данных по годам, а затем применить diff и Delt к каждому столбцу, соответствующим образом переименовать столбцы, а затем 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 голосов
/ 01 января 2012

Я думал, что стратегия плавления и последующей обработки в категориях индикатора была излишне сложной.Если вы хотели получить кадр данных с добавленной строкой 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) )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...