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功能如下applymatrix

我假设你想要的是矩阵

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 回答