Есть ли уже функция для вычитания различных переменных в последующих кварталах? - PullRequest
1 голос
/ 10 ноября 2011

У меня несбалансированный квартальный набор данных с пропущенными значениями.Я хочу вычесть переменную A2 из A1 в последующих кварталах.Обратите внимание, что я не хочу получать отличия от A2, но вычитать РАЗНЫЕ переменные друг от друга.Различия должны рассчитываться отдельно для каждого идентификатора.Помимо того, что меняются годы, такие как Q4 1999 и Q1 2000.

Я действительно не уверен, должен ли я здесь конкатенировать свой временной индекс, поскольку пакеты типа zoo принимают только один индекс.Но это не проблема здесь.Вот некоторые примеры данных:

structure(list(uid = c(1, 1, 1, 2, 2, 3, 3, 3), tndx = c(1999.4, 
2000.1, 2000.2, 1999.4, 2000.1, 2000.1, 2000.2, 2000.3), A1 = c(2, 
2, 2, 10, 11, 1, 1, 1), A2 = c(3, 3, 3, 14, 14, 2, 100, 2)), .Names = c("uid", 
"tndx", "A1", "A2"), row.names = c(NA, -8L), class = "data.frame")

# which results in
  uid   tndx A1  A2
1   1 1999.4  2   3
2   1 2000.1  2   3
3   1 2000.2  2   3
4   2 1999.4 10  14
5   2 2000.1 11  14
6   3 2000.1  1   2
7   3 2000.2  1 100
8   3 2000.3  1   2  

Если вы предпочитаете отдельный индекс, используйте этот пример:

# Thx Andrie!
x2 <- data.frame(x, colsplit(x$tndx, "\\.", names=c("year", "qtr")))

Есть ли хороший способ решить эту проблему с помощью reshape2, plyr или даже базовый, или вы бы предпочли написать пользовательскую функцию?

Обратите внимание, также возможно, что некоторые uid встречаются только один раз.Очевидно, что вы не можете рассчитать лаговую разницу.Тем не менее, мне нужно проверить это и создать NA.

Ответы [ 2 ]

2 голосов
/ 10 ноября 2011

Мы разбиваем его на uid, используя by, и внутри функции, которая работает с каждым набором строк для одного uid, мы создаем объект зоопарка z, используя класс yearqtr дляиндекс.Затем мы объединяем временной ряд с пустым рядом, имеющим все желаемые кварталы, включая любые недостающие промежуточные четверти, дающие zm, и выполняем вычисление, дающее zz.Наконец мы конвертируем в форму data.frame на выходе:

library(zoo)
to.yearqtr <- function(x) as.yearqtr(trunc(x) + (10*(x-trunc(x))-1)/4)

DF <- do.call("rbind", by(x, x$uid, function(x) {
    # columns of x are: uid tndx A1 A2
    z <- zoo(x[c("A1", "A2")], to.yearqtr(x$tndx))
    zm <- merge(z, zoo(, seq(start(z), end(z), 1/4)))
    zz <- with(zm, cbind(zm, `A1 - A2 lag` = A1 - lag(A2, -1)))
    if (ncol(zz) <= ncol(z)) zz$`A1 - A2 lag` <- NA # append NA if col not added
    data.frame(uid = x[1, 1], tndx = time(zz), coredata(zz), check.names = FALSE)
}))

, что дает это:

> DF
    uid    tndx A1 A2 result A1 - A2 lagged
1.1   1 1999 Q4  2  3     NA             NA
1.2   1 2000 Q1  2  2     NA             -1
1.3   1 2000 Q2  2  3     NA              0
2.1   2 1999 Q4  2  4     NA             NA
2.2   2 2000 Q1 NA NA     NA             NA
2.3   2 2000 Q2 NA NA     NA             NA
2.4   2 2000 Q3 NA NA     NA             NA
2.5   2 2000 Q4 NA NA     NA             NA
2.6   2 2001 Q1  3  4     NA             NA
3.1   3 2000 Q1  1  2     NA             NA
3.2   3 2000 Q2  1 NA     NA             -1
3.3   3 2000 Q3  1  2     NA             NA

РЕДАКТИРОВАТЬ: Полностью пересмотрел решение на основе дальнейшего обсуждения.Обратите внимание, что это не только добавляет дополнительный столбец, но также конвертирует индекс в класс "yearqtr" и добавляет дополнительные пропущенные строки.

EDIT: некоторые незначительные упрощения в функции by.

1 голос
/ 10 ноября 2011

Мне не совсем понятно, что вы хотели узнать, потому что вы не указали «правильный ответ».Если вы хотите вычесть одну переменную с задержкой из другой переменной без отметки, вы можете сделать это со смещением индексации.(Вам нужно дополнить результат, если вы хотите его вернуть, чтобы вернуть его обратно в фрейм данных.

 x$A1lagA2 <- ave(x[, c("A1", "A2")], x$uid, FUN=function(z) {
            with(z, c(NA, A1[2:NROW(z)] -A2[1:(NROW(z)-1)]) ) } )[[1]]
 x
  uid   tndx A1  A2 A1lagA2
1   1 1999.4  2   3      NA
2   1 2000.1  2   3      -1
3   1 2000.2  2   3      -1
4   2 1999.4 10  14      NA
5   2 2000.1 11  14      -3
6   3 2000.1  1   2      NA
7   3 2000.2  1 100      -1
8   3 2000.3  1   2     -99

Вы получаете надоедливые дублирующие дополнительные столбцы с помощью ave (), когда аргумент является многоколоночным, но я просто взялпервый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...