Вычисление расстояния между двумя переменными и генерация новой переменной - PullRequest
0 голосов
/ 11 мая 2019

Я хотел бы создать переменную с именем spill, которая определяется как сумма расстояний между векторами каждой строки, умноженная на стоимость акций. Например, рассмотрим

firm  us  euro  asia  africa  stock  year
A     1    4     3      5      46    2001
A     2    0     1      3      889   2002
B     2    3     1      1      343   2001
B     0    2     1      3      43    2002
C     1    3     4      2      345   2001

Я хотел бы создать вектор, который в основном берет расстояние между двумя фирмами в момент времени t и генерирует переменную разлива. Например, для фирмы А в 2001 году это будет 0,204588 (что является косинусным расстоянием между фирмой А и В в момент времени t, т. Е. В 2001 году (1,4,3,5) и (2,3,1, 1) (т. Е. Сходство инвестиций в нас, евро, азии, африке), а затем умножить на 343, а затем вычислить расстояние между А и С в 2001 году как .10528 * 345, следовательно, переменная разлива равна = 0,2045883 * 343 + 0,1052075 * 345 = 106,4704 за 2001 год для фирмы A.

Я хочу получить таблицу с разливом вот так

firm  us  euro  asia  africa  stock  year  spill
A     1    4     3      5      46    2001  106.4704 
A     2    0     1      3      889   2002    
B     2    3     1      1      343   2001    
B     0    2     1      3      43    2002    
C     1    3     4      2      345   2001    

Может кто-нибудь, пожалуйста, посоветовать?

Вот коды для stata [https://www.statalist.org/forums/forum/general-stata-discussion/general/1409182-calculating-distance-between-two-variables-and-generating-new-variable]. У меня около 3000 фирм и 30 лет. Работает хорошо, но очень медленно.

dt <- data.frame(id=c("A","A","B","B","C"),us=c(1,2,2,0,1),euro=c(4,0,3,2,3),asia=c(3,1,1,1,4),africa=c(5,3,1,3,2),stock=c(46,889,343,43,345),year=c(2001,2002,2001,2002,2001))

1 Ответ

2 голосов
/ 11 мая 2019

Учитывая минимальную информацию о том, как рассчитать расстояние сходства, я использовал формулу из Найти косинусное сходство между двумя массивами , которое будет возвращать числа, отличные от вашего, но должно давать ту же самую результирующую информацию.

Я разбил данные по годам, чтобы мы могли сравнить уникальные идентификаторы.Я беру эти отдельные списки и использую lapply для запуска цикла for, сравнивающего все возможности.

dt <- data.frame(id=c("A","A","B","B","C"), us=c(1,2,2,0,1),euro=c(4,0,3,2,3),asia=c(3,1,1,1,4),africa=c(5,3,1,3,2),stock=c(46,889,343,43,345),year=c(2001,2002,2001,2002,2001))

geo <- c("us","euro","asia","africa")
s <- lapply(split(dt, dt$year), function(a) {
  n <- nrow(a)
  for(i in 1:n){
    csim <- rep(0, n) # reset results of cosine similarity *stock vector
    for(j in 1:n){
      x <- unlist(a[i,geo])
      y <- unlist(a[j,geo])
      csim[j] <- (1-(x %*% y / sqrt(x%*%x * y%*%y)))*a[j,"stock"]
    }
    a$spill[i] <- sum(csim)
  }
  a
})

do.call(rbind, s)
#       id us euro asia africa stock year     spill
#2001.1  A  1    4    3      5    46 2001 106.47039
#2001.3  B  2    3    1      1   343 2001  77.93231
#2001.5  C  1    3    4      2   345 2001  72.96357
#2002.2  A  2    0    1      3   889 2002  12.28571
#2002.4  B  0    2    1      3    43 2002 254.00000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...