比较每一行,并在R中指定数字和总数

时间:2014-04-17 03:33:30

标签: r matrix compare rows

我是R的新手,我曾经在stackoverflow中引用了很多。 我想将每一行与其余行进行比较,以计算修改后的相似度矩阵。

mat <- matrix("", 10, 12)
mat[c(1, 4, 6),] <- sample(c("AA", "AB", "BB"), 18, TRUE)
mat[c(2, 3, 10),] <- sample(c("AA", "BB", "AB"), 18, TRUE)
mat[c(5, 8),] <- sample(c("BB", "AB", "BB"), 12, TRUE)
mat[c(7, 9),] <- sample(c("AA", "AA", "BB"), 12, TRUE)
mat[3,4] = 'NA'
mat[2,5] = 'NA'

这提供了:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
 [1,] "AA" "AA" "AB" "AA" "AA" "AA" "AA" "AA" "AB" "AA"  "AA"  "AA" 
 [2,] "AB" "AA" "BB" "BB" "NA" "AB" "AB" "AA" "BB" "BB"  "BB"  "AB" 
 [3,] "BB" "AA" "AB" "NA" "AA" "AA" "BB" "AA" "AB" "AA"  "AA"  "AA" 
 [4,] "AA" "AA" "BB" "AB" "AA" "AB" "AA" "AA" "BB" "AB"  "AA"  "AB" 
 [5,] "AB" "AB" "BB" "BB" "AB" "AB" "AB" "AB" "BB" "BB"  "AB"  "AB" 
 [6,] "AA" "AA" "AB" "AA" "AB" "AA" "AA" "AA" "AB" "AA"  "AB"  "AA" 
 [7,] "BB" "AA" "AA" "BB" "AA" "AA" "BB" "AA" "AA" "BB"  "AA"  "AA" 
 [8,] "AB" "BB" "BB" "BB" "AB" "BB" "AB" "BB" "BB" "BB"  "AB"  "BB" 
 [9,] "AA" "AA" "BB" "BB" "AA" "AA" "AA" "AA" "BB" "BB"  "AA"  "AA" 
[10,] "BB" "AB" "AA" "BB" "BB" "BB" "BB" "AB" "AA" "BB"  "BB"  "BB" 

我想将每行与其余行进行比较,以计算修改后的相似度矩阵。

第1步: 通过比较两行来分配值

AA Vs AA = 1;
AA Vs AB = 0.5;
AA Vs NA = 0.0;
NA Vs NA = 0.0;
AB Vs AA = 0.5;
AA Vs BB = 0.0;
AB Vs AB = 0.5

第2步: 总分(例如第1行与第2行= 7.0)

第3步: 计算除了存在一个或两个“NA”的实例之外的总数(示例第1行与第2行= 11.0),

第4步: 将总分除以计数(例如第1行与第2行7/11 = 0.636363)

第5步: 对每一行进行操作,并在两个对角线中填充矩阵(例10 X 10)

提前致谢!

1 个答案:

答案 0 :(得分:0)

我会稍微改变你的矩阵定义,使"NA"个字符成为实际缺失值(NA),这些值在R中具有与你想要的行为接近的特殊含义。

mat <- matrix("", 10, 12)
mat[c(1, 4, 6),] <- sample(c("AA", "AB", "BB"), 18, TRUE)
mat[c(2, 3, 10),] <- sample(c("AA", "BB", "AB"), 18, TRUE)
mat[c(5, 8),] <- sample(c("BB", "AB", "BB"), 12, TRUE)
mat[c(7, 9),] <- sample(c("AA", "AA", "BB"), 12, TRUE)
mat[3,4] <- NA
mat[2,5] <- NA

您还没有提供所有可能匹配的值,因此我将做出一些假设。可以在不破坏代码的情况下更改这些值。

对于第1步,我将创建一个可以使用聚集在一起的对名称进行索引的命名向量。因此AA与BA成为'AABA'

pair <- c('AAAA', 'AAAB', 'AABB', 'ABAB', 'ABBB', 'BBBB')
value <- c(1, 0.5, 0, 0.5, 0.5, 1)
# add reverse pairing (I am assuming symmetry)
pair <- c(pair, paste0(substr(pair, 3, 4), substr(pair, 1, 2)))
value <- c(value, value)
names(value) <- pair

检查向量value如何看待这一点,以确保它符合您的要求。接下来,我们定义一个使用此全局定义向量的函数,并在步骤4结束时返回所需的内容。您可能希望在函数体中包含向量定义,但我觉得这样效率不高。

compare <- function(row1, row2){
  # get total value of match from 2 vectors
  # get vector of complete cases (not having any NAs)
  good.cases <- complete.cases(cbind(row1, row2))
  na.cases <- length(row1) - good.cases
  total.value <- sum(value[paste0(row1, row2)], na.rm=TRUE) + 0.5*na.cases
  total.value/good.cases
}

此时我通过比较前两行获得了6.5的total.value,但这可能是由于value中的错误假设。

对于第5步,我们使用双循环:

# start empty matrix with match values
n <- nrow(mat)
matches <- matrix(rep(NA, n*n), nrow=n)
for (i in 1:n){
  for (j in i:n){  ## if symmetric, only half matrix is enough
    matches[i, j] <- compare(mat[i, ], mat[j, ])
  }
}

我希望有所帮助。

修改:更改了compare(),以便在评论中的请求后为NA案例分配值。