通过使用 xor()
函数可以识别出位翻转,而从 xor()
函数的结果中累加可得到位翻转的总数。我没有优化 hamm_dist_min()
中的代码。
xor(0,0)
xor(1,1)
xor(0,1)
xor(1,0)
根据OP的要求,计算汉明距离的两个方向。例如:AB、BA、AC、CA、BC和CB,这些形成了三元组ABC、BCA和CAB。如果您只想要一个方向,例如:AB、AC和BC,您可以在hamm_dist_min()函数中使用combn()函数设置列号。
数据:
A = matrix( c(1, 0, 0, 0, 1, 0, 0, 0, 1), nrow=3, ncol=3, byrow = TRUE)
dimnames(A) = list(c("Taxa1", "Taxa2", "Taxa3"), c("A1", "B1", "C1"))
df <- data.frame("ID" = c("A1", "B1", "C1"), "Triplicate" = c("T1", "T1", "T1"))
海明距离
hamm_dist_min <- function(data)
{
n_col <- ncol(data)
x <- expand.grid(seq_len(n_col), seq_len(n_col))
x <- x[ x[, 1] != x[, 2], ]
x <- x[order(x[, 1]), ]
x <- split(x, cut(x[, 1], breaks = c(0, seq_len(n_col)), labels = colnames(data) ))
h_d <- unlist(lapply(x, function(y){
min( colSums(apply(y, 1, function(z) xor(data[, z[1]], data[, z[2]]))))
}))
return(h_d)
}
hamm_dist_min(data = A)
df$Hamming <- hamm_dist_min(data = A)
df
Youtube示例:
df1 <- matrix( c(0,1,1,1,1,1,0,0), ncol = 2, byrow = FALSE)
colnames(df1) <- LETTERS[1:2]
hamm_dist_min(data = df1)
编辑:
基于问题中新增的数据集。
注意:如果一个样本类型只有一列,则将0作为汉明距离,因为我们需要至少2列来计算汉明距离。看一下df
的三个副本列中的T71。您可以返回NA
,表示不可用
,而不是值0。
load("Hamming.RData")
col_list <- unique(unlist(lapply( colnames(A), function(x){
substr(x = x, start = 1, stop = nchar(x) - 1)
} )
))
my_results <- lapply( col_list, function(x){
cols_x <- grep(x, colnames(A) )
if(length(cols_x) == 1 ){
return( setNames( object = rep( 0, length(cols_x)), nm = colnames(A)[cols_x]))
} else{
return(hamm_dist_min(data = A[, cols_x]))
}
})
triplicate <- paste0( "T", rep(seq_along(my_results),
lengths(my_results)))
my_results <- unlist(my_results)
df <- data.frame( SampleID = names( my_results ),
Hamming = my_results,
Triplicate = triplicate,
stringsAsFactors = FALSE )
head(df)
triplicate
变量所需的方式分组答案。 - Manasi Shah