我有一个类似于此
的数据集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
}
但这很慢。我查看了使用by
和tapply
,但没有弄清楚如何使它们正常工作。
我认为XTS或TS不会因为User元素而起作用。
有什么建议吗?
答案 0 :(得分:9)
您可以使用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)] )
)
答案 1 :(得分:4)
我认为最简单的方法,特别是考虑进行进一步分析,是将数据框转换为pdata.frame
类的plm
类。
从diff()
和lag()
转换后,运算符可用于创建面板滞后和差异。
df<-pdata.frame(df,index=c("id","date")
df<-transofrm(df, l_value=lag(value,1))
答案 2 :(得分:2)
我偶然发现了一个类似的问题,并编写了一个函数。
#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")
答案 3 :(得分:1)
如果您没有时间变量的空白,请执行
df %>% group_by(User) %>% mutate(value_lag = lag(value, order_by =Date)
如果时间变量确实存在间隙,请参阅此答案 https://stackoverflow.com/a/26108191/3662288
答案 4 :(得分:1)
对于没有丢失障碍的面板,这是一个直观的解决方案:
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
答案 5 :(得分:0)
同样,您可以使用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)])))
这个想法完全相同:取值,按用户拆分,然后在每个子集上运行一个函数。 unlist将其恢复为矢量格式。
答案 6 :(得分:0)
如果表按用户和日期排序,则可以使用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
答案 7 :(得分:0)
现在在CRAN上可用的 collapse 软件包提供了最通用的基于C / C ++的解决方案,以(完全识别)面板滞后,引线,差异和增长率/对数差异。它具有通用功能flag
,fdiff
和fgrowth
,以及相关的滞后/超前,差值和增长算子L
,F
,D
和G
。因此,要滞后面板数据集,只需键入:
L(data, n = 1, by = ~ idvar, t = ~ timevar, cols = 4:8)
表示:计算data
的第4列到第8列的1个滞后,分别由idvar
和timevar
标识。可以提供多个ID和时间变量,即~ id1 + id2
,也可以在每一列上计算滞后和超前的顺序(即n = -1:3
计算一个领先和三个滞后)。使用flag
也可以通过编程方式完成同一件事:
flag(data[4:8], 1, data$idvar, data$timevar)
在典型的数据集(<30,000 obs。)上,这两个选项的计算结果均低于1毫秒。大数据性能类似于data.tables移动。类似的编程适用于差异fdiff / D
和增长率fgrowth / G
。这些函数都是S3通用的,并具有矢量/时间序列,矩阵/ ts矩阵,data.frame以及plm::pseries
和plm::pdata.frame
和grouped_df
方法。因此,它们可以与plm
类一起用于面板数据和dplyr。