R在不平衡面板数据集中填充多个时间序列

时间:2018-04-16 19:39:15

标签: r panel-data padr

我按ID显示每日收入(和其他变量)的面板数据集,其中0收入的日期未报告。我希望用0填充这些空白作为我的分析,这意味着对于每个ID的时间序列,我需要确保每天都有观察。每个系列都可以在与其他系列不同的日期开始或结束。我一直试图使用" padr"包,但我一直得到一个"未使用的参数"使用以下示例代码时出错:

library(padr)
library(dplyr)
#unbalanced panel data
ID <- c(1,1,1,1,
        2,2,2,2,2,2,
        3,3,3,3,3,3,3,
        4,4,4)
DT <-  today() + c(1,3,4,5, #ID = 1
                  3,4,7,8,9,10, #ID = 2
                  2,5,6,7,8,9,10, #ID = 3
                  8,10,11) #ID = 4

#The end date denote the max date for each ID
EndDT <-  today() + c(5,5,5,5, #ID = 1
                      13,13,13,13,13,13, #ID = 2
                      10,10,10,10,10,10,10, #ID = 3
                      15,15,15) #ID = 4

#random variables v1 and v2 to represent revenue and other variables
set.seed(1)
v1 <- rnorm(20,mean = 10000, sd = 5)
v2 <- rnorm(20,mean = 5000, sd = 1.5)

df <- as.data.frame(cbind(ID,DT,EndDT,v1,v2))

#format to simpler date
df$DT <- as.Date(DT, origin="1970-01-01")
df$EndDT <- as.Date(EndDT, origin="1970-01-01")

df_padded <- arrange(df,ID,DT) %>%
          pad(by='DT',group='ID', end_val='EndDT') %>%
          fill_by_value(v1,v2, value=0)

我的错误讯息:

Error in pad(., by = "DT", group = "ID", end_val = "EndDT") : 
  unused argument (group = "ID")

非欢迎不涉及padr的答案。

3 个答案:

答案 0 :(得分:0)

在与padr争吵一段时间之后,我决定编写自己的函数。此函数适用于示例集,但很快就遇到了实际数据的问题。无论哪种方式,我认为这可能对其他人有用,所以这里是:

date.pad <- function(df, date.var, group, replace.vars, new.val=0){
  require("dplyr")
  require("lazyeval")
  require("lubridate")
  tempdf1 <- arrange_(df,group,date.var)
  finaldf <- tempdf1[0,]
  unique.id <- unique(tempdf1[,group])
  nonreplaced.vars <- setdiff(colnames(tempdf1),replace.vars)
  nonreplaced.vars <- nonreplaced.vars[!nonreplaced.vars==date.var]

  for(i in seq_along(unique.id)){
    filter_criteria <- interp(~y==x, .values=list(y=as.name(group),x=i)) #necessary for NSE
    tempdf2 <- filter_(tempdf1,filter_criteria) 
    min.date <- min(tempdf2[[date.var]])
    max.date <- max(tempdf2[[date.var]])
    all.days <- as.Date(seq(min.date,max.date,by="days"),origin="1970-01-01")
    distinct.days <- unique(tempdf2[,date.var])
    app.days <- as.Date(setdiff(all.days,distinct.days),origin="1970-01-01")
    tempdf3 <- tempdf2[0,]

      for(n in seq_along(app.days)){
          tempdf3[n,date.var] <- app.days[n]
      }
      for(j in seq_along(nonreplaced.vars)){
          tempdf3[1:nrow(tempdf3),nonreplaced.vars[j]] <- tempdf2[1,nonreplaced.vars[j]]
      }
      finaldf <- bind_rows(finaldf,tempdf3)
  }
  finaldf[replace.vars] <-new.val
  finaldf <- bind_rows(finaldf,df) %>% arrange_(group,date.var)
  return(finaldf)
} 

for.exmpl <- date.pad(df=df1, date.var="DT", group="ID", replace.vars=c("v1","v2"), new.val=0)
for.exmpl

答案 1 :(得分:0)

这是我设计的一个新答案,它在我的一个应用程序之外更加适用,并且使用的代码更少:

library(tidyverse)

temp <- group_by(df1,ID) %>%
        complete(DT = seq.Date(min(DT),max(EndDT),by="day")) %>%
        fill(EndDT,sometext) %>%
        arrange(ID,DT)
temp[is.na(temp)] <- 0
View(temp)

结果是:

# A tibble: 33 x 6
# Groups:   ID [4]
      ID DT         EndDT          v1    v2 sometext
   <dbl> <date>     <date>      <dbl> <dbl> <chr>   
 1    1. 2018-05-04 2018-05-08  9997. 5001. textvar
 2    1. 2018-05-05 2018-05-08     0.    0. textvar
 3    1. 2018-05-06 2018-05-08 10001. 5001. textvar
 4    1. 2018-05-07 2018-05-08  9996. 5000. textvar
 5    1. 2018-05-08 2018-05-08 10008. 4997. textvar
 6    2. 2018-05-06 2018-05-16 10002. 5001. textvar
 7    2. 2018-05-07 2018-05-16  9996. 5000. textvar
 8    2. 2018-05-08 2018-05-16     0.    0. textvar
 9    2. 2018-05-09 2018-05-16     0.    0. textvar
10    2. 2018-05-10 2018-05-16 10002. 5000. textvar
# ... with 23 more rows

(请忽略“sometext”变量。我在下面测试我的函数时创建了它。)

答案 2 :(得分:0)

您的代码无法运行,因为您在end_val参数中指定了一个字符。这应该是Date,您只能在所有组中指定一个日期。

为了使用padr执行您想要的操作,您应该组合DT和EndDT列。这种方式对于每个ID,其最终日期出现在DT列中:

df %>% 
  group_by(ID) %>% 
  summarise(DT = max(EndDT)) %>% 
  mutate(v1 = NA, v2 = NA) %>% 
  bind_rows(df %>% select(-EndDT), .) %>% 
  group_by(ID, DT) %>% 
  filter(row_number() == 1) %>% 
  group_by(ID) %>% 
  pad()