R: данные панели plm: как использовать трубы?

У меня есть некоторые данные панели, которые выглядят так (код для ввода моего набора данных находится в конце):

  countrycode year X
1         ARG 2015 2
2         ARG 2016 2
3         ARG 2017 1
4         AUS 2015 1
5         AUS 2016 3
6         AUS 2017 2
7         USA 2015 6
8         USA 2016 5
9         USA 2017 8

И я хотел бы изменить переменную X (т.е. вычесть X прошлого года из X этого года). Он отлично работает, когда я не использую трубы:

library(tidyverse)
library(plm)

pdf <- pdata.frame(df, index = c("countrycode", "year"))

# This works perfectly
pdf <- mutate(pdf, dX = pdf$X - lag(pdf$X))

Результаты именно то, что я хотел бы: каждое значение dX 2015 года является NA, потому что нет значения X 2014 года для сравнения.

  countrycode year X dX
1         ARG 2015 2 NA
2         ARG 2016 2  0
3         ARG 2017 1 -1
4         AUS 2015 1 NA
5         AUS 2016 3  2
6         AUS 2017 2 -1
7         USA 2015 6 NA
8         USA 2016 5 -1
9         USA 2017 8  3

Но когда я пытаюсь использовать %>% :

pdf <- pdf %>% mutate(dX2 = X - lag(X))

результаты больше не учитывают структуру панели. Посмотрите, как dX2 пытается изменить ситуацию в разных странах? Таким образом, dX2 для США в 2015 году должен быть NA, но вместо этого он равен 4.

  countrycode year X dX dX2
1         ARG 2015 2 NA  NA
2         ARG 2016 2  0   0
3         ARG 2017 1 -1  -1
4         AUS 2015 1 NA   0
5         AUS 2016 3  2   2
6         AUS 2017 2 -1  -1
7         USA 2015 6 NA   4
8         USA 2016 5 -1  -1
9         USA 2017 8  3   3

Есть ли способ использовать каналы в plm или с панельными данными?

Полный код здесь:

library(tidyverse)
library(plm)

df <- data.frame(stringsAsFactors=FALSE,
   countrycode = c("ARG", "ARG", "ARG", "AUS", "AUS", "AUS", "USA", "USA",
                   "USA"),
          year = c(2015L, 2016L, 2017L, 2015L, 2016L, 2017L, 2015L, 2016L,
                   2017L),
             X = c(2L, 2L, 1L, 1L, 3L, 2L, 6L, 5L, 8L)
)
df

# using panel
pdf <- pdata.frame(df, index = c("countrycode", "year"))

# This works perfectly
pdf <- mutate(pdf, dX = pdf$X - lag(pdf$X))
pdf

# Pipe doesn't work across the panel
pdf <- pdf %>% mutate(dX2 = X - lag(X))
pdf

person Jeremy K.    schedule 09.10.2018    source источник


Ответы (2)


Нужно указать, что вы используете лаг от dplyr (а не plm).

pdf <- pdf %>% 
  group_by(countrycode) %>%
  mutate(dX2 = X - dplyr::lag(X))

Полученные результаты:

  countrycode year X dX dX2
1         ARG 2015 2 NA  NA
2         ARG 2016 2  0   0
3         ARG 2017 1 -1  -1
4         AUS 2015 1 NA   NA
5         AUS 2016 3  2   2
6         AUS 2017 2 -1  -1
7         USA 2015 6 NA   NA
8         USA 2016 5 -1  -1
9         USA 2017 8  3   3
person Randall Helms    schedule 09.10.2018
comment
Ваш код дает тот же результат, что и мой выше (мой желаемый результат - чтобы dX2 соответствовал dX, имея в нем NA). Я пробовал mutate(dX2 = X - dplyr::lag(X)) и пробовал mutate(dX2 = X - plm::lag(X)), но ни один из них не дает такого же результата, как код без конвейера (который дает dX). - person Jeremy K.; 09.10.2018
comment
Я отредактировал свой первый ответ, включив в него group_by (код страны). Это работает для вас сейчас? - person Randall Helms; 10.10.2018

Я считаю, что это имеет ту же причину, что и почему

with(pdf, X - lag(X))

не дает ожидаемого ответа (относительно структуры панели), но:

[1] NA  0 -1  0  2 -1  4 -1  3

Вычисление с with() происходит внутри первого аргумента, и при таком доступе к pdata.frame используется самая внутренняя структура pdata.frame, где столбец является не объектом pseries, а типом голой кости (например, числовым). При доступе к столбцу pdata.frame с помощью средства доступа $ столбец становится pseries в этот момент, и используется правильный метод lag, который может учитывать структуру панели.

Я предполагаю, что конструкция eval в определении оператора канала (%>%) оценивает свой первый аргумент таким же образом.

(Это недостаток текущего определения объекта pdata.frame).

person Helix123    schedule 09.10.2018