我试图估计在给定时间步骤(日期)中给定区域中有多少个人(唯一" id" s),在下一个时间步骤中离开该区域。这是数据的一小部分:
zone date id
802 2007-01-01 453444
803 2007-01-01 407680
803 2007-01-01 415786
804 2007-02-01 407680
802 2007-02-01 453444
802 2007-03-01 415786
804 2007-03-01 407680
802 2007-04-01 415786
802 2007-04-01 407680
804 2007-04-01 453444
801 2007-05-01 453444
804 2007-05-01 407680
804 2007-05-01 415786
804 2007-06-01 453444
801 2007-06-01 415786
804 2007-06-01 407680
803 2007-07-01 407680
803 2007-07-01 453444
804 2007-07-01 415786
所以我的问题是,我如何估计这些离开?我正在尝试创建一个矩阵,看起来像下面的每个日期/区域总和的个体数量。非常感谢您提供的任何帮助。
zone 2005-07-01 2005-08-01 2005-09-01
1 103 0 1 0
2 106 0 0 3
3 107 0 0 0
4 1603 0 0 0
5 1607 0 0 0
6 2204 0 0 0
7 2206 0 3 1
8 2209 0 0 0
9 3106 0 0 0
10 3804 0 0 0
11 3806 0 0 0
我正在思考类似于两步功能的事情1.)遍历所有个别ID,询问date [t]中的zone [i] = date [t + 1]中的zone [i],如果不会产生" 1"并存储在一个矩阵中(表示离开);然后2.)对所有ID中的每个区域/日期的所有1进行求和,得出每个时间步长的每个区域的离开总和。这样的事情,但在制定这个功能时遇到了麻烦
答案 0 :(得分:0)
新答案:
因此,第一步是按id
和zone
对数据进行分组,并计算每次离开的次数。这可以通过以下方式完成:
all.dates = data.frame(date=unique(zz$date))
n=nrow(all.dates)
bool.list = by(data=zz, INDICES=list(zz$zone, zz$id), FUN=function(x){
xx = merge(x,all.dates,by=c('date'),all=T)
xx$id[is.na(xx$id)] = 0
return(diff(xx$id)<0)
})
返回指示离开的列表:
> bool.list
: 801
: 407680
[1] FALSE FALSE TRUE FALSE FALSE FALSE
--------------------------------------------------------------------------
: 802
: 407680
[1] FALSE FALSE FALSE TRUE FALSE FALSE
--------------------------------------------------------------------------
: 803
: 407680
[1] TRUE FALSE FALSE FALSE FALSE FALSE
--------------------------------------------------------------------------
: 804
: 407680
[1] FALSE TRUE FALSE FALSE FALSE TRUE
--------------------------------------------------------------------------
: 801
: 415786
[1] FALSE FALSE FALSE FALSE FALSE TRUE
--------------------------------------------------------------------------
[...]
此列表可以轻松转换为矩阵:
tmp = matrix(unlist(bool.list),ncol=nrow(all.dates)-1,byrow=T)
colnames(tmp) = all.dates$date[2:nrow(all.dates)]
rownames(tmp) = rep(rownames(bool.list), length(colnames(bool.list)))
返回:
> tmp
2007-02-01 2007-03-01 2007-04-01 2007-05-01 2007-06-01 2007-07-01
801 FALSE FALSE TRUE FALSE FALSE FALSE
802 FALSE FALSE FALSE TRUE FALSE FALSE
803 TRUE FALSE FALSE FALSE FALSE FALSE
804 FALSE TRUE FALSE FALSE FALSE TRUE
801 FALSE FALSE FALSE FALSE FALSE TRUE
802 FALSE FALSE FALSE TRUE FALSE FALSE
803 TRUE FALSE TRUE FALSE FALSE FALSE
804 FALSE FALSE FALSE FALSE TRUE FALSE
801 FALSE FALSE FALSE FALSE TRUE FALSE
802 FALSE TRUE FALSE FALSE FALSE FALSE
803 FALSE FALSE FALSE FALSE FALSE FALSE
804 FALSE FALSE FALSE TRUE FALSE TRUE
第二步是折叠具有相同ID的所有行,并计算TRUE
值的数量。这可以通过以下方式完成:
result = aggregate(tmp,list(rownames(tmp)),FUN=sum)
返回:
> result
Group.1 2007-02-01 2007-03-01 2007-04-01 2007-05-01 2007-06-01 2007-07-01
1 801 0 0 1 0 1 1
2 802 0 1 0 2 0 0
3 803 2 0 1 0 0 0
4 804 0 1 0 1 1 2
应该是理想的答案。
旧回答:
这是我最好的猜测,只要您没有指定如何处理重复数据:
# we extract all the dates:
# they will define the number of columns of the returned matrix
all.dates = data.frame(date=unique(zz$date))
bool.list = by(data=zz, INDICES=list(zz$id), FUN=function(x){
if (any(duplicated(x$date))) {
x = x[!duplicated(x$date),]
}
# we complete so we have all dates represented, for each ID and each zone
xx = merge(x,all.dates,all=T)
return(diff(xx$zone)==0)
}
)
# we build the matrix from the list vectors
r = matrix(unlist(tst),ncol=nrow(all.dates)-1,nrow=length(names(tst)),byrow=T)
# some cosmetic job
colnames(r) = all.dates$date[2:nrow(all.dates)]
rownames(r) = names(bool.list)
对于您的示例,这将返回:
> r
2007-02-01 2007-03-01 2007-04-01 2007-05-01 2007-06-01 2007-07-01
407680 FALSE FALSE FALSE FALSE TRUE FALSE
415786 NA NA FALSE TRUE FALSE FALSE
453444 TRUE NA NA FALSE FALSE FALSE
您可能希望将NA替换为对您有意义的任何值(TRUE
或FALSE
)
注意部分:
if (any(duplicated(x$date))) {
x = x[!duplicated(x$date),]
}
这是我删除相同date
和相同id
的第二个区域数据的地方,如果重复的话。您可能希望修改它以使用另一种方法处理凌乱的数据:)