【问题标题】:general lag in time series panel data时间序列面板数据的一般滞后
【发布时间】:2012-02-13 04:19:35
【问题描述】:

我有一个类似的数据集

User    Date        Value
A       2012-01-01  4
A       2012-01-02  5   
A       2012-01-03  6
A       2012-01-04  7
B       2012-01-01  2
B       2012-01-02  3   
B       2012-01-03  4
B       2012-01-04  5

我想创建 Value 的滞后,尊重 User

User    Date        Value   Value.lag
A       2012-01-01  4       NA
A       2012-01-02  5       4
A       2012-01-03  6       5
A       2012-01-04  7       6
B       2012-01-01  2       NA
B       2012-01-02  3       2   
B       2012-01-03  4       3
B       2012-01-04  5       4

我在一个循环中做的非常低效

df$value.lag1<-NA
levs<-levels(as.factor(df$User))
levs
  for (i in 1:length(levs)) {
    temper<- subset(df,User==as.numeric(levs[i]))
    temper<- rbind(NA,temper[-nrow(temper),])  
df$value.lag1[df$User==as.numeric(as.character(levs[i]))]<- temper
      }

但这很慢。我看过使用bytapply,但不知道如何让它们工作。

我不认为 XTS 或 TS 会因为 User 元素而起作用。

有什么建议吗?

【问题讨论】:

  • 我认为plm 包对这种类型的数据有一个实现。

标签: r time-series lag


【解决方案1】:

您可以使用ddply:它将一个 data.frame 切割成片段并转换每个片段。

d <- data.frame( 
  User = rep( LETTERS[1:3], each=10 ),
  Date = seq.Date( Sys.Date(), length=30, by="day" ),
  Value = rep(1:10, 3)
)
library(plyr)
d <- ddply( 
  d, .(User), transform,
  # This assumes that the data is sorted
  Value = c( NA, Value[-length(Value)] ) 
)

【讨论】:

  • 以下stackoverflow.com/questions/1296646/…排序可以用arrange()完成
  • 这是最适合我的解决方案!您能否展示我们如何使用相同的流程,但要领先而不是滞后?我有一个面板数据,其中所有参与者的时间点都不统一。
【解决方案2】:

我认为最简单的方法,尤其是考虑进行进一步分析,是将您的数据框从plm 包转换为pdata.frame 类。

diff()lag() 运算符转换后可用于创建面板差异和滞后。

df<-pdata.frame(df,index=c("id","date"))  
df<-transform(df, l_value=lag(value,1))   

【讨论】:

  • 优雅的答案——在转换为 pdata.frame 后,仅使用 lag() 作为新变量计算时间延迟也可以!
【解决方案3】:

对于没有丢失 obs 的面板,这是一个直观的解决方案:

df <- data.frame(id = c(1, 1, 1, 1, 1, 2, 2), 
                 date = c(1992, 1993, 1991, 1990, 1994, 1992, 1991), 
                 value = c(4.1, 4.5, 3.3, 5.3, 3.0, 3.2, 5.2))

df<-df[with(df, order(id,date)), ]  # sort by id and then by date
df$l_value=c(NA,df$value[-length(df$value)]) # create a new var with data displaced by 1 unit
df$l_value[df$id != c(NA, df$id[-length(df$id)])] =NA # NA data with different current and lagged id.
df

id date value l_value
4  1 1990   5.3      NA
3  1 1991   3.3     5.3
1  1 1992   4.1     3.3
2  1 1993   4.5     4.1
5  1 1994   3.0     4.5
7  2 1991   5.2      NA
6  2 1992   3.2     5.2

【讨论】:

    【解决方案4】:

    我偶然发现了一个类似的问题并写了一个函数。

    #df needs to be a structured balanced paneldata set sorted by id and date
    #OBS the function deletes the row where the NA value would have been.
    
    df <- data.frame(id = c(1, 1, 1, 1, 1, 2, 2,2,2,2), 
                     date = c(1992, 1993, 1991, 1990, 1994, 1992, 1991
                              ,1994,1990,1993), 
                     value = c(4.1, 4.5, 3.3, 5.3, 3.0, 3.2, 5.2,5.3,3.4,5.6))
    # sort paneldata set
    library(dplyr)
    df<-arrange(df,id,date)
    
    #Function
    # a=df
    # b=colname of variable/variables that you want to lag
    # q=number of lag years
    # t=colname of date/time column
    retraso<-function(a,b,q,t){
    
      sto<-max(as.numeric(unique(a[[t]])))
      sta<-min(as.numeric(unique(a[[t]])))
    
      yo<-a[which(a[[t]]>=(sta+q)),]
    
      la<-function(a,d,t,sto,sta){
    
    
        ja<-data.frame(a[[d]],a[[t]])
        colnames(ja)<-c(d,t)
    
    
        ja<-ja[which(ja[[t]]<=(sto-q)),1]
        return(ja)
      }
    
      for (i in 1:length(b)){
    
        yo[[b[i]]] <-la(a,b[i],t,sto,sta)
    
        }
        return(yo)
    
      }
    
    #lag df 1 year
    df<-retraso(df,"value",1,"date")
    
    

    【讨论】:

      【解决方案5】:

      如果你在时间变量中没有间隙,那么做

      df %>% group_by(User) %>% mutate(value_lag = lag(value, order_by =Date)
      

      如果您确实在时间变量中有间隙,请参阅此答案 https://stackoverflow.com/a/26108191/3662288

      【讨论】:

        【解决方案6】:

        同样,您可以使用tapply

        # Create Data
        user = c(rep('A',4),rep('B',4))
        date = rep(seq(as.Date('2012-01-01'),as.Date('2012-01-04'),1),2)
        value = c(4:7,2:5) 
        df = data.frame(user,date,value)
        # Get lagged values
        df$value.lag = unlist(tapply(df$value, df$user, function(x) c(NA,x[-length(df$value)])))
        

        想法完全一样:取值,按用户拆分,然后在每个子集上运行一个函数。取消列表将其恢复为矢量格式。

        【讨论】:

          【解决方案7】:

          如果表格按用户和日期排序,则可以使用zoo 完成。诀窍是此时不要指定索引。

          library(zoo)
          df <-read.table(text="User Date Value
          A 2012-01-01 4
          A 2012-01-02 5
          A 2012-01-03 6
          A 2012-01-04 7
          B 2012-01-01 2
          B 2012-01-02 3
          B 2012-01-03 4
          B 2012-01-04 5", header=TRUE, as.is=TRUE,sep = " ")
          
          out <-zoo(df)
          
          Value.lag <-lag(out,-1)[out$User==lag(out$User)]
          res <-merge.zoo(out,Value.lag)
          res <-res[,-(4:5)]  # to remove extra columns
          
            User.out Date.out   Value.out Value.Value.lag
          1 A        2012-01-01 4         <NA>           
          2 A        2012-01-02 5         4              
          3 A        2012-01-03 6         5              
          4 A        2012-01-04 7         6              
          5 B        2012-01-01 2         <NA>           
          6 B        2012-01-02 3         2              
          7 B        2012-01-03 4         3              
          8 B        2012-01-04 5         4 
          

          【讨论】:

            【解决方案8】:

            CRAN 现在提供的collapse 软件包为(完全识别的)面板滞后、领先、差异和增长率/对数差异提供了最通用的基于 C/C++ 的解决方案。它具有通用函数flagfdifffgrowth 以及相关的滞后/领先、差异和增长运算符LFDG。因此,要滞后面板数据集,输入以下内容就足够了:

            L(data, n = 1, by = ~ idvar, t = ~ timevar, cols = 4:8)
            

            这意味着:计算data 的第 4 到第 8 列的 1 个滞后,由 idvartimevar 标识。可以提供多个 ID 和时间变量,即~ id1 + id2,并且还可以在每一列上计算滞后和超前序列(即n = -1:3 计算一个超前和 3 个滞后)。同样的事情也可以通过flag以编程方式完成:

            flag(data[4:8], 1, data$idvar, data$timevar)
            

            这两个选项在典型数据集(fdiff / D 和增长率fgrowth / G。这些函数都是 S3 通用的,具有向量/时间序列、矩阵/ts-matrix、data.frame,以及plm::pseriesplm::pdata.framegrouped_df 方法。因此,它们可以与面板数据的plm 类和 dplyr 一起使用。

            【讨论】:

              猜你喜欢
              • 2019-07-23
              • 1970-01-01
              • 2021-07-06
              • 2018-04-15
              • 1970-01-01
              • 1970-01-01
              • 2012-10-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多