计算比率并将它们放入R中的矩阵中

时间:2013-03-18 23:08:29

标签: r matrix

我有一个类似于这个的表,并且想要计算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 vs all 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函数,我在这里做错了。

3 个答案:

答案 0 :(得分:2)

您可以使用expand.gridapplymatrix功能实现您想要的效果,如下所示

我假设你想要的是像

那样的矩阵
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

答案 1 :(得分: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="")

答案 2 :(得分: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]])
}

希望有所帮助!