如果输入文件是距离矩阵,是否有任何R包可以获得成对距离列表 例如,如果我的输入是像这样的data.frame:
A1 B1 C1 D1
A1 0 0.85 0.45 0.96
B1 0 0.85 0.56
C1 0 0.45
D1 0
我希望输出为:
A1 B1 0.85
A1 C1 0.45
A1 D1 0.96
B1 C1 0.85
B1 D1 0.56
C1 D1 0.45
我发现了一个问题,即使用包' reshape'来执行相反的功能。但无法调整它以获得我想要的东西。
答案 0 :(得分:7)
如果您有data.frame
,可以执行以下操作:
df <- structure(list(A1 = c(0, 0, 0, 0), B1 = c(0.85, 0, 0, 0), C1 = c(0.45,
0.85, 0, 0), D1 = c(0.96, 0.56, 0.45, 0)), .Names = c("A1", "B1",
"C1", "D1"), row.names = c(NA, -4L), class = "data.frame")
data.frame( t(combn(names(df),2)), dist=t(df)[lower.tri(df)] )
X1 X2 dist
1 A1 B1 0.85
2 A1 C1 0.45
3 A1 D1 0.96
4 B1 C1 0.85
5 B1 D1 0.56
6 C1 D1 0.45
如果将其作为带有行+列名的matrix
的另一种方法是直接使用reshape2
:
mat <- structure(c(0, 0, 0, 0, 0.85, 0, 0, 0, 0.45, 0.85, 0, 0, 0.96,
0.56, 0.45, 0), .Dim = c(4L, 4L), .Dimnames = list(c("A1", "B1",
"C1", "D1"), c("A1", "B1", "C1", "D1")))
library(reshape2)
subset(melt(mat), value!=0)
Var1 Var2 value
5 A1 B1 0.85
9 A1 C1 0.45
10 B1 C1 0.85
13 A1 D1 0.96
14 B1 D1 0.56
15 C1 D1 0.45
答案 1 :(得分:6)
其他几个选项:
生成一些数据
D <- dist(cbind(runif(4), runif(4)), diag=TRUE, upper=TRUE) # generate dummy data
m <- as.matrix(D) # coerce dist object to a matrix
dimnames(m) <- dimnames(m) <- list(LETTERS[1:4], LETTERS[1:4])
假设您只想要距离矩阵的上三角形定义的对的距离,您可以这样做:
xy <- t(combn(colnames(m), 2))
data.frame(xy, dist=m[xy])
# X1 X2 dist
# 1 A B 0.3157942
# 2 A C 0.5022090
# 3 A D 0.3139995
# 4 B C 0.1865181
# 5 B D 0.6297772
# 6 C D 0.8162084
或者,如果您希望所有对的距离(在两个方向上):
data.frame(col=colnames(m)[col(m)], row=rownames(m)[row(m)], dist=c(m))
# col row dist
# 1 A A 0.0000000
# 2 A B 0.3157942
# 3 A C 0.5022090
# 4 A D 0.3139995
# 5 B A 0.3157942
# 6 B B 0.0000000
# 7 B C 0.1865181
# 8 B D 0.6297772
# 9 C A 0.5022090
# 10 C B 0.1865181
# 11 C C 0.0000000
# 12 C D 0.8162084
# 13 D A 0.3139995
# 14 D B 0.6297772
# 15 D C 0.8162084
# 16 D D 0.0000000
或以下,它排除了任何NA
距离,但没有保留列/行名称(尽管这很容易纠正,因为我们有列/行索引):
data.frame(which(!is.na(m), arr.ind=TRUE, useNames=FALSE), dist=c(m))
答案 2 :(得分:3)
我想你有一个列联表或矩阵定义如下:
mat = matrix(c(0, 0.85, 0.45, 0.96, NA, 0, 0.85, 0.56, NA, NA, 0, 0.45, NA,NA,NA,0), ncol=4)
cont = as.table(t(mat))
# A B C D
#A 0.00 0.85 0.45 0.96
#B 0.00 0.85 0.56
#C 0.00 0.45
#D 0.00
然后您只需要进行data.frame转换,并删除NA / 0&#39;
df = as.data.frame(cont)
df = df[complete.cases(df),]
df[df[,3]!=0,]
# Var1 Var2 Freq
#5 A B 0.85
#9 A C 0.45
#10 B C 0.85
#13 A D 0.96
#14 B D 0.56
#15 C D 0.45
答案 3 :(得分:0)
以下是使用spaa-package。
的示例exampleInput <- structure(list(A1 = c(0, 0, 0, 0), B1 = c(0.85, 0, 0, 0),
C1 = c(0.45, 0.85, 0, 0), D1 = c(0.96, 0.56, 0.45, 0)),
.Names = c("A1", "B1", "C1", "D1"), row.names = c(NA, -4L), class = "data.frame")
library(spaa)
pairlist <- dist2list(as.dist(t(exampleInput)))
pairlist[as.numeric(pairlist$col) > as.numeric(pairlist$row),]
输出:
col row value
2 B1 A1 0.85
3 C1 A1 0.45
4 D1 A1 0.96
7 C1 B1 0.85
8 D1 B1 0.56
12 D1 C1 0.45