【问题标题】:Calculating distance between two variables and generating new variable计算两个变量之间的距离并生成新变量
【发布时间】:2019-05-11 00:08:15
【问题描述】:

我想创建一个名为溢出的变量,它是每行向量之间的距离之和乘以库存值。例如,考虑

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 年的公司 A,它将是 0.204588(这是公司 A 和 B 在时间 t 之间的余弦距离,即在 2001 年 (1,4,3,5) 和 (2,3,1, 1)(即美国、欧元、亚洲、非洲的投资相似度),然后乘以343,然后计算2001年A和C之间的距离为0.10528 * 345,因此溢出变量= 0.2045883 * 343 + 0.1052075 * 345 = 2001 年公司 A 的 106.4704。

我想要一张这样的桌子,包括溢出物

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]的代码。我有大约 3,000 家公司和 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))

【问题讨论】:

  • 你还没有完全阐述如何计算你想要的。比如你说的。你能解释一下你是如何一步一步得到103.1的吗?例如,您说 ` .2 * 343+.1 * 345 = 103.1 ` 但是您从哪里得到 .2 或 .1?你也有.10528 * 345,但你在哪里使用它?你的解释是模棱两可的。可能这就是为什么到目前为止没有人帮助你的原因。你需要清楚。不要假设人们知道你想要什么,而是明确解释
  • 我认为他们分别对余弦距离进行了四舍五入。所以 0.204588 变成了 .2 而 .10528 变成了 .1。
  • 期望 R 用户阅读 stata 代码并直觉你的启发式和近似值是不现实的。请扩展问题正文中的文本并明确定义您的规则。也可以使用你在 R 中的任何代码。这样我们可以更好地了解从哪里开始。请记住,SO 不是代码服务器。您应该展示自己的进步程度以及需要帮助解决的错误或障碍。

标签: r dplyr data.table


【解决方案1】:

鉴于有关如何计算相似距离的最少信息,我使用了来自 Find cosine similarity between two arrays 的公式,该公式将返回与您的不同的数字,但应该给出相同的结果信息。

我按年份拆分数据,以便我们可以比较唯一 ID。我使用这些单独的列表并使用 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

【讨论】:

    猜你喜欢
    • 2018-08-11
    • 2020-09-07
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-15
    相关资源
    最近更新 更多