【问题标题】:Write algorithm to identify symptom pairs编写算法来识别症状对
【发布时间】:2017-09-28 09:17:36
【问题描述】:

由于我是新的 R 用户,我正在努力编写循环或类似的方法来解决以下问题。

所以问题: 我有一个包含 200 名患者和 30 个症状的列表,其中信息症状存在是 (1) 或否 (0)。我想创建一个类似于相关矩阵的矩阵,每对症状都会告诉我这两种症状在同一个人身上出现的百分比。

所以:

ID /sym 1 / sym 2 / sym 3 /....
Pat 1 / 1 / 1 / 0 / ...    
Pat 2 / 1 / 1 / 1 /
Pat 3 / 1 / 1 / 0 / 
...

然后我想使用一个看起来像标准相关矩阵的矩阵,但对于每个症状对都显示两者的百分比,因为我认为关联这些分类值没有任何意义。

到目前为止,我已经开始为每个组合编写一个新变量,告诉我两者是否都存在,然后用它来计算百分比并将其填充到我的矩阵中。

不幸的是,考虑到可能的组合数量,这需要 FOREVER 来编写,但我不知道如何迭代它。也许你能帮忙?它可能非常简单,但我还不足以让程序员想到它。

【问题讨论】:

    标签: r


    【解决方案1】:

    设 x 为 200 x 30 的数据数组。根据矩阵乘法的规则,x' * x 是一个 30 x 30 的数组,其 (i,j) 项计算列 i 和 j 等于 1 的位置数。将这些计数除以 200 得到比例并将其乘以 100将其转换为所需的百分比。

    这里是单行实现以及用于测试和说明它的代码。对于比您的问题大 10,000 倍的问题(20,000 名患者和 3000 个症状),在这台机器上执行大约需要 10 秒。由于它几乎与大小呈线性关系,因此您的问题的计算应该需要大约一毫秒。

    #
    # For columns i and j, f(x)[i,j] is the percentage of rows in which
    # both columns of `x` are TRUE (optionally: nonzero).
    #
    f <- function(x) (t(x) %*% x) * (100 / dim(x)[1])
    #
    # Slow version to demonstrate `f` is correct.
    #
    f.direct <- function(x) {
      m <- dim(x)[1]
      n <- dim(x)[2]
      #
      # Test all elements of `x` to create a logical array.
      #
      x.indicator <- x != 0
      #
      # Initialize the result.
      #
      y <- matrix(NA_real_, n, n)
      #
      # Loop over pairs of columns.
      #
      for (i in 1:n) {
        for (j in 1:n) {
          # Compare column `i` to column `j` by averaging the times their
          # indicators are equal.  Multiply by 100 to give a percentage.
          y[i,j] <- 100 * mean(x.indicator[,i] & x.indicator[,j])
        }
      }
      return(y)
    }
    #------------------------------------------------------------------------------#
    #
    # Create some data and test `f` on them.
    #
    m <- 200  # Number of rows
    n <- 30   # Number of columns
    p <- 0.1  # Expected proportion of 1's
    x <- matrix(runif(m*n) < p, m, n)
    
    system.time(y <- f(x))                # Almost instantaneous
    system.time(y.direct <- f.direct(x))  # A thousand times slower (but not bad)
    #
    # Display the results.
    #
    par(mfrow=c(1,2))
    image(y, main="Matrix Result")
    image(y.direct, main="Direct Result")
    par(mfrow=c(1,1))
    #
    # Compare them and report the outcome.
    #
    if(all.equal(y, y.direct)) cat("Results are equal.") else cat("There's a difference!")
    

    【讨论】:

    • 非常感谢!我会用周末的时间来理解这一点!
    • 好的,所以我一直在尝试重现您的代码:代码本身有效,但生成的矩阵应该有一个只有 1 的对角线,因为这是将症状相互比较,所以它们是 100%展示。运行您的代码时,我得到一个比其他对角线更高的对角线,但在查看实际 y 矩阵时不是 100%。我在这里做错了吗?再次感谢您的帮助!
    • 这不是 100%,也不应该是:您要求“因为每对症状都告诉我这两种症状在同一个人身上出现的百分比。”因此,当一种症状与其自身配对时,您应该获得具有该症状的所有个体的比例。如果这不是您想要的,请通过编辑帖子来阐明您的要求。考虑提供一个简单的例子。 (我确信这种技术很容易修改以产生您可能正在寻找的这个数字的任何变化。)
    • 啊,好的,谢谢。不,我可以处理这个!我只是想明白。谢谢!
    • 很遗憾我的点赞只被记录下来,没有显示出来
    猜你喜欢
    • 2010-11-15
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 2010-10-07
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    相关资源
    最近更新 更多