There are several ways how you can get a lagged variable within a group. First of all you should sort the data, so that in each group the time is sorted accordingly.
First let us create a sample data.frame:
> set.seed(13)
> dt <- data.frame(location = rep(letters[1:2], each = 4), time = rep(1:4, 2), var = rnorm(8))
> dt
location time var
1 a 1 0.5543269
2 a 2 -0.2802719
3 a 3 1.7751634
4 a 4 0.1873201
5 b 1 1.1425261
6 b 2 0.4155261
7 b 3 1.2295066
8 b 4 0.2366797
Define our lag function:
lg <- function(x)c(NA, x[1:(length(x)-1)])
Then the lag of variable within group can be calculated using tapply
:
> unlist(tapply(dt$var, dt$location, lg))
a1 a2 a3 a4 b1 b2 b3 b4
NA 0.5543269 -0.2802719 1.7751634 NA 1.1425261 0.4155261 1.2295066
Using ddply
from package plyr:
> ddply(dt, ~location, transform, lvar = lg(var))
location time var lvar
1 a 1 -0.1307015 NA
2 a 2 -0.6365957 -0.1307015
3 a 3 -0.6417577 -0.6365957
4 a 4 -1.5191950 -0.6417577
5 b 1 -1.6281638 NA
6 b 2 0.8748671 -1.6281638
7 b 3 -1.3343222 0.8748671
8 b 4 1.5431753 -1.3343222
Speedier version using data.table
from package data.table
> ddt <- data.table(dt)
> ddt[,lvar := lg(var), by = c("location")]
location time var lvar
[1,] a 1 -0.1307015 NA
[2,] a 2 -0.6365957 -0.1307015
[3,] a 3 -0.6417577 -0.6365957
[4,] a 4 -1.5191950 -0.6417577
[5,] b 1 -1.6281638 NA
[6,] b 2 0.8748671 -1.6281638
[7,] b 3 -1.3343222 0.8748671
[8,] b 4 1.5431753 -1.3343222
Using lag
function from package plm
> pdt <- pdata.frame(dt)
> lag(pdt$var)
a-1 a-2 a-3 a-4 b-1 b-2 b-3 b-4
NA 0.5543269 -0.2802719 1.7751634 NA 1.1425261 0.4155261 1.2295066
Using lag
function from package dplyr
> dt %>% group_by(location) %>% mutate(lvar = lag(var))
Source: local data frame [8 x 4]
Groups: location
location time var lvar
1 a 1 0.5543269 NA
2 a 2 -0.2802719 0.5543269
3 a 3 1.7751634 -0.2802719
4 a 4 0.1873201 1.7751634
5 b 1 1.1425261 NA
6 b 2 0.4155261 1.1425261
7 b 3 1.2295066 0.4155261
8 b 4 0.2366797 1.2295066
Last two approaches require conversion from data.frame
to another object, although then you do not need to worry about sorting. My personal preference is the last one, which was not available when writing the answer initially.
Update: Changed the data.table code to reflect the developments of the data.table package, pointed out by @Hibernating.
Update 2: Added dplyr example.