3

18x18 のデータ フレームがあり、2 つの列のペアごとに 18 行の値が互いに比較されるように、列のすべての可能なペアを互いに比較したいと考えています。

私のデータは大きすぎてここに載せることができないので、これまでに思いついたことの小さな例を書きました:

> a <- c(1:18)
> b <- c(18:1)
> c <- c(1:9,18:10)
data <- as.data.frame(matrix(c(a,b,c), ncol = 3, nrow = 18))
> data
   V1 V2 V3
1   1 18  1
2   2 17  2
3   3 16  3
4   4 15  4
5   5 14  5
6   6 13  6
7   7 12  7
8   8 11  8
9   9 10  9
10 10  9 18
11 11  8 17
12 12  7 16
13 13  6 15
14 14  5 14
15 15  4 13
16 16  3 12
17 17  2 11
18 18  1 10

たとえば、列 V1 と V3 を比較したいのですが、両方の列 (V1 と V3) の等しい値には 0 が割り当てられ、最初の列 (V1) の値が大きい場合は 1 が割り当てられ、 2 番目の列 (V3) が大きい場合、2 が割り当てられます。次のコードを使用して、ペアごとに手動でこれを実行し、結果を新しいデータ フレーム freqcomp に変換できます。

> freqcomp <- as.data.frame(table(ifelse(data[,1]==data[,3],0,ifelse(data[,1]>data[,3],1,ifelse(data[,1]<data[,3],2,NA)))))
> 
> freqcomp
  Var1 Freq
1    0   10
2    1    4
3    2    4

私が持っているすべての列に対してこの比較を自動化するにはどうすればよいですか? すべての列または使用できる他の関数を実行するための素敵な for ループはありますか?

4

1 に答える 1

3

とを使用する必要がありcombn()ますapply()

apply(combn(1:length(data), 2), 2, function(x) {
    as.data.frame(table(
        factor(sign(data[,x[1]] - data[,x[2]]), levels=c(0,1,-1), labels=c(0,1,2))
    ))
})

(読みやすくするために複数行に分割)。

それは私に与えます:

[[1]]
  Var1 Freq
1    0    0
2    1    9
3    2    9

[[2]]
  Var1 Freq
1    0   10
2    1    4
3    2    4

[[3]]
  Var1 Freq
1    0    0
2    1    9
3    2    9

編集: 各 data.frame の列に名前を付けるのは簡単です:

apply(combn(1:length(data), 2), 2, function(x) {
    result <- as.data.frame(table(
        factor(sign(data[,x[1]] - data[,x[2]]), levels=c(0,1,-1), labels=c(0,1,2))
    ))
    colnames(result)[1] <- paste(x, collapse="|")
    return(result)
})
于 2013-03-12T21:48:22.120 に答える