我按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的答案。
答案 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()