我有一个不平衡的面板数据集,它为我提供了银行在不同领域贷款的信息。地理id和银行id是使用类似egen id=group(var)
的Stata命令创建的数字变量。
地理id从1变为n,银行id从1到k。为了让您更具体地了解我的数据:
Geography ID (gid) | Bank ID (bid) | lending
-----------------------------------------------
1 | 1 | 25
1 | 2 | 32
1 | 4 | 83
----------------------------------------------
2 | 1 | 76
2 | 3 | 22
---------------------------------------------
3 | 2 | 42
3 | 3 | 12
3 | 5 | 22
--------------------------------------------
我的最终目标是创建一个具有所有地理区域成对组合的数据帧,例如:
1 2 3 ......... n
-------------------------------
1|(1,1) (1,2) (1,3)......(1,n)
2|(2,1) (2,2) (2,3)......(2,n)
.| . . .
n|(n,1) . ......(n,n)
使得条目(i,j)
给我:
(i,j)=(Lending from Banks Operating in Area i and j)/(Total Lending in Area i and j)
例如,给定上述数据
(1,1)=1 (1,2)=(25+76)/(25+32+83+76+22) (1,3)=(32+42)/(25+32+83+42+12+22)
我有一种感觉,作为第一步,我应该在循环中使用levelsof
和bysort
,但我不确定如何准确地解决这个问题。
即使你不能提供确切的解决方案,如果能得到任何帮助或建议,我将不胜感激。虽然我更喜欢Stata,但我也有一些Matlab/R的知识,所以如果你认为它更适合这个问题,我愿意接受建议。
这里有一个R方法:
x <- data.frame(
geoid = c(1,1,1, 2,2, 3,3,3),
bankid = c(1,2,4, 1,3, 2,3,5),
lending = c(25,32,83, 76,22, 42,12,22)
)
myfunc <- function(x, i, j) {
geos <- x$geoid %in% c(i, j)
banks <- with(x, intersect(bankid[geoid == i], bankid[geoid == j]))
with(x, sum(lending[geos & bankid %in% banks]) / sum(lending[geos]))
}
outer(unique(x$geoid), unique(x$geoid),
function(i,j) mapply(myfunc, list(x), i, j))
# [,1] [,2] [,3]
# [1,] 1.0000000 0.4243697 0.3425926
# [2,] 0.4243697 1.0000000 0.1954023
# [3,] 0.3425926 0.1954023 1.0000000
这不是最有效的,但这是一个开始。很难(我认为(真正矢量化,因为每个子集都需要交集,尽管我相信这可以优化,不需要为每个等价对重新计算两次intersect(bankid...)
(如果这是一个性能因素的话(。
编辑:不重新计算等效geoid
:对的过程稍微高效一些
按地理划分数据:
geox <- split(x, x$geoid)
myfunc <- function(i, j) {
if (i >= j) return(NA)
banks <- intersect(geox[[i]]$bankid, geox[[j]]$bankid)
sum(with(geox[[i]], lending[ bankid %in% banks ]),
with(geox[[j]], lending[ bankid %in% banks ])) /
sum(geox[[i]]$lending, geox[[j]]$lending)
}
o <- outer(seq_along(geox), seq_along(geox),
function(i,j) mapply(myfunc, i, j))
o
# [,1] [,2] [,3]
# [1,] NA 0.4243697 0.3425926
# [2,] NA NA 0.1954023
# [3,] NA NA NA
(只是为了证明我们只计算了最小集。(现在,将上三角形的数据翻转到下三角形:
o[which(lower.tri(o),TRUE)] <- o[which(upper.tri(o),TRUE)]
o
# [,1] [,2] [,3]
# [1,] NA 0.4243697 0.3425926
# [2,] 0.4243697 NA 0.1954023
# [3,] 0.3425926 0.1954023 NA
并将已知值1分配给对角线:
diag(o) <- 1