Справка по кодированию на Stata - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть несбалансированный набор данных панели, который дает мне информацию о том, сколько банков кредитуют в разных областях.Географический идентификатор и идентификатор банка - это числовые переменные, которые были созданы с помощью команды Stata, например egen id=group(var).

Идентификатор географии изменяется от 1 до n, а идентификатор банка - от 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, поэтому, если вы считаете, что она более подходит для этой проблемы, я открыт для предложений.

1 Ответ

0 голосов
/ 15 ноября 2018

Вот метод 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
...