我是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)
提前致谢!
答案 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案例分配值。