2017-09-28 9 views
1

私は新しい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/
... 

私はその後、標準の相関行列のように見える行列を使用したいが、すべての症状ペアの両方の存在の割合を示すだろう意味をなさない。

これまで私は、両方の変数が存在するかどうかを知らせる新しい変数をすべての組み合わせに書き始めてから、それを使ってパーセンテージを計算し、それを行列に埋めました。

残念ながら、それは可能な組み合わせの量を与えて書き込みを永遠に取るが、私はそれを反復する方法を理解することはできません。多分あなたは助けることができますか?それはおそらく非常に簡単で、私はそれを考えてプログラマが足りません。

答えて

1

xを200×30のデータ配列とします。行列の乗算の規則によって、x '* xは30行30列の配列であり、その(i、j)項目は列iとjが1に等しい場所の数を数えます。これらの数を200で割るとその割合に100を掛けますそれを所望のパーセンテージに変換する。

ここでは、コードをテストして説明するための1行の実装を示します。問題の10,000倍(20,000人の患者と3000の症状)で、このマシンで実行するのに約10秒かかります。ほぼ線形にサイズに比例するので、問題の計算には約1ミリ秒かかるでしょう。

# 
# 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!") 
+0

ありがとうございました! 私はこれを理解しようと週末を過ごすでしょう! – herbert

+0

さて、私はコードを再現しようとしています。コード自体は機能しますが、結果の行列は1つの対角線を持つ必要があります。あなたのコードを実行すると、残りの部分よりも高い対角線が得られますが、実際のy行列を見ると100%ではありません。私はここで何か間違っていますか?あなたの助けをもう一度ありがとう! – herbert

+0

それは100%ではありませんし、そうでなければなりません:あなたは「すべての症状の対が同じ人に存在する両方の症状の割合を教えてくれました」と要求しました。症状がそれ自身と対になっている場合は、その症状を持つすべての人の割合を取得する必要があります。これがあなたが望むものでない場合は、投稿を編集してリクエストを明確にしてください。簡単な例を提供することを検討してください。 (私は、このテクニックがあなたが探しているかもしれないこの番号のどんなバリエーションを作り出すように簡単に修正されていると確信しています。) – whuber

関連する問題