1

このようなテーブルがあり、列 A と B の比率を計算したいと考えています。たとえば、次のようになります。

             A    B     C     D    E     F
     [1,]  187  174   183   115  101   104
     [2,]  451  166   177   842  101   133
     [3,]  727  171   187 12803   98   134
     [4,] 1532  181   196   730   98   108
     [5,] 4139  188   214 20358  105   159
     [6,]  689  185   211  1633  110   162
     [7,] 1625  184   195  2283  109   114
     [8,]  771  181   190   904  105   110
     [9,]  950  177   190  1033  106   112
    [10,]  703  180   191   463  106   110
    [11,] 2052  178   188  2585  100   105
    [12,] 1161  178   187  2874   99   110
    [13,]  214  175   184   173   98   110
    [14,]  473  184   191   971  104   111
    [15,]  756  185   193 14743  107   114

次のように、前の行をすべて新しい行と列 (15 行と 15 列) として持つ新しいマトリックスを作成したいと思います (括弧内の値は、計算された比率のプレースホルダーです)。

          [,1]    [,2]     [,3]    [,4]    
 [1,]  (A1:B1) (A1:B2)  (A1:B3) (A1:B4) ...   
 [2,]  
 [3,]  
 [4,] 
 ...

これは最良の例ではないかもしれませんが、あまり混乱しないことを願っています。A1:B1、A2:B2、A3:B3 の比率を計算するには、次のようにします。

data.matrix(data["A"]/data["B"])

そして、すべての人にそれを行うには、次のようにします。

data.matrix(data[1,]/data[1,1])
data.matrix(data[1,]/data[1,2])
...

等々。これは大変な作業のようで、誰かがより迅速で効率的な方法を知っているかもしれません。

編集

この機能は機能すると思っcombnていましたが、そうではないことがわかりました。次のような 2 列の行列がある場合:

       A       B
 [1,]  187   115
 [2,]  451   842
 [3,]  727 12803
 [4,] 1532   730
 [5,] 4139 20358
 [6,]  689  1633
 [7,] 1625  2283
 [8,]  771   904
 [9,]  950  1033
[10,]  703   463
[11,] 2052  2585
[12,] 1161  2874
[13,]  214   173
[14,]  473   971
[15,]  756 14743

そして、このcombn関数を使用して、考えられるすべての比率 (A1:B1、A1:B2、... A2:B1、A2:B2...) を計算します。A1 と B のすべての値の結果だけを取得します。

> combn(ncol(data), 2, function(x) data[,x[1]]/data[,x[2]])
 [,1]
 [1,] 1.62608696
 [2,] 0.53562945
 [3,] 0.05678357
 [4,] 2.09863014
 [5,] 0.20331074
 [6,] 0.42192284
 [7,] 0.71178274
 [8,] 0.85287611
 [9,] 0.91965150
[10,] 1.51835853
[11,] 0.79381044
[12,] 0.40396660
[13,] 1.23699422
[14,] 0.48712667
[15,] 0.05127857

または、機能を理解していないだけで、combnここで何か間違ったことをしているのかもしれません。

4

3 に答える 3

2

expand.grid以下のように、applyおよびmatrix関数を使用して、目的を達成できます。

あなたが望むのはマトリックスのようなものだと思います

A1/B1  A1/B2  A1/B3  ...
A2/B1  A2/B2  A2/B3  ...
...    ...    ...    ...
...    ...    ...    ...

これを行うコードは次のとおりです。コメントでの説明

txt <- "A    B     C     D    E     F\n187  174   183   115  101   104\n451  166   177   842  101   133\n727  171   187 12803   98   134\n1532  181   196   730   98   108\n4139  188   214 20358  105   159\n689  185   211  1633  110   162\n1625  184   195  2283  109   114\n771  181   190   904  105   110\n950  177   190  1033  106   112\n703  180   191   463  106   110\n2052  178   188  2585  100   105\n1161  178   187  2874   99   110\n214  175   184   173   98   110\n473  184   191   971  104   111\n756  185   193 14743  107   114"

data <- as.matrix(read.table(textConnection(txt), header = TRUE))

# expand.grid : creates every combination of one element each from column A and
# B with elements of B repeated first 

# apply : calls function(x) { x[1]/x[2]) } for every combination outputted by 
# expand.grid 

# matrix : converts the result of apply into matrix. dimnames arguments sets 
# rownames and colnames for easy  verification for us

result <- matrix(apply(expand.grid(data[, "A"], data[, "B"]), 1, function(x) x[1]/x[2]), 
    nrow = nrow(data), dimnames = list(data[, "A"], data[, "B"]))

# note that we have set rownames for result to be values of A and colnames for
# result to be value of B
result
##            174       166       171       181        188       185       184
## 187   1.074713  1.126506  1.093567  1.033149  0.9946809  1.010811  1.016304
## 451   2.591954  2.716867  2.637427  2.491713  2.3989362  2.437838  2.451087
## 727   4.178161  4.379518  4.251462  4.016575  3.8670213  3.929730  3.951087
## 1532  8.804598  9.228916  8.959064  8.464088  8.1489362  8.281081  8.326087
## 4139 23.787356 24.933735 24.204678 22.867403 22.0159574 22.372973 22.494565
## 689   3.959770  4.150602  4.029240  3.806630  3.6648936  3.724324  3.744565
## 1625  9.339080  9.789157  9.502924  8.977901  8.6436170  8.783784  8.831522
## 771   4.431034  4.644578  4.508772  4.259669  4.1010638  4.167568  4.190217
## 950   5.459770  5.722892  5.555556  5.248619  5.0531915  5.135135  5.163043
## 703   4.040230  4.234940  4.111111  3.883978  3.7393617  3.800000  3.820652
## 2052 11.793103 12.361446 12.000000 11.337017 10.9148936 11.091892 11.152174
## 1161  6.672414  6.993976  6.789474  6.414365  6.1755319  6.275676  6.309783
## 214   1.229885  1.289157  1.251462  1.182320  1.1382979  1.156757  1.163043
## 473   2.718391  2.849398  2.766082  2.613260  2.5159574  2.556757  2.570652
## 756   4.344828  4.554217  4.421053  4.176796  4.0212766  4.086486  4.108696
##            181       177       180       178       178       175       184
## 187   1.033149  1.056497  1.038889  1.050562  1.050562  1.068571  1.016304
## 451   2.491713  2.548023  2.505556  2.533708  2.533708  2.577143  2.451087
## 727   4.016575  4.107345  4.038889  4.084270  4.084270  4.154286  3.951087
## 1532  8.464088  8.655367  8.511111  8.606742  8.606742  8.754286  8.326087
## 4139 22.867403 23.384181 22.994444 23.252809 23.252809 23.651429 22.494565
## 689   3.806630  3.892655  3.827778  3.870787  3.870787  3.937143  3.744565
## 1625  8.977901  9.180791  9.027778  9.129213  9.129213  9.285714  8.831522
## 771   4.259669  4.355932  4.283333  4.331461  4.331461  4.405714  4.190217
## 950   5.248619  5.367232  5.277778  5.337079  5.337079  5.428571  5.163043
## 703   3.883978  3.971751  3.905556  3.949438  3.949438  4.017143  3.820652
## 2052 11.337017 11.593220 11.400000 11.528090 11.528090 11.725714 11.152174
## 1161  6.414365  6.559322  6.450000  6.522472  6.522472  6.634286  6.309783
## 214   1.182320  1.209040  1.188889  1.202247  1.202247  1.222857  1.163043
## 473   2.613260  2.672316  2.627778  2.657303  2.657303  2.702857  2.570652
## 756   4.176796  4.271186  4.200000  4.247191  4.247191  4.320000  4.108696
##            185
## 187   1.010811
## 451   2.437838
## 727   3.929730
## 1532  8.281081
## 4139 22.372973
## 689   3.724324
## 1625  8.783784
## 771   4.167568
## 950   5.135135
## 703   3.800000
## 2052 11.091892
## 1161  6.275676
## 214   1.156757
## 473   2.556757
## 756   4.086486
于 2013-03-19T02:43:32.333 に答える
1

編集:質問を誤解しているようです。答えは、次を使用するとさらに簡単outerです。

# gives the same 15*15 matrix as geektrader's
outer(mm[,1], mm[,2], '/')

古い答え (不正解):

使用する必要がありますcombn

# combn(ncol(mm), 2) gives you all possible combinations
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
# [1,]    1    1    1    1    1    2    2    2    2     3     3     3     4     4     5
# [2,]    2    3    4    5    6    3    4    5    6     4     5     6     5     6     6

# it also accepts a function argument. we can use it to divide 
# respective columns
mm.div <- combn(ncol(mm), 2, function(x) mm[,x[1]]/mm[,x[2]])

# set column names the matrix
colnames(mm.div) <- combn(colnames(mm), 2, paste, collapse="")
于 2013-03-18T23:12:42.613 に答える
0

ここで要点を完全に見逃しているかもしれませんが、for ループをいくつか使用しないのはなぜですか? 簡単な関数を書いたので、ペアを渡すことができます。

例えば:

A <- rnorm(15)
B <- rnorm(15)
data <- data.frame(A,B)

ratio <- function(input1, input2){
    out <- matrix(0, nrow=length(input1), ncol=length(input1))
    k <- 1
    for (i in 1:length(input1)){
        for (j in 1:length(input1)){
            out[k, j] <- input1[k] / input2[j]
        }
        k <- k + 1
    }
    return(out)
}

ratio(data$A, data$B)

編集

別の考え。次に、この関数を使用して比率のすべての可能なペアを実行するには、次のように別の for ループを追加するだけです。

combs <- combn(1:4, 2)
out <- list()
for (i in 1:(length(combs)/2)){
    out[[i]] <- ratio(data[,combs[1,i]], data[,combs[2,i]])
}

それが役立つことを願っています!

于 2013-03-19T02:40:32.393 に答える