统计两行数据帧R之间的匹配数
我有一个数据框,如下所示:统计两行数据帧R之间的匹配数,r,compare,rows,R,Compare,Rows,我有一个数据框,如下所示: LA LE LI LO LU A 1 0 0 0 0 B 0 0 1 1 1 C 0 0 0 0 0 D
LA LE LI LO LU
A 1 0 0 0 0
B 0 0 1 1 1
C 0 0 0 0 0
D 1 0 0 0 0
E 1 0 1 1 0
我想计算两行之间有多少个值匹配,但不计算匹配的0,只计算匹配的1。例如,AxE=1,BxE=2,但在某种程度上,我将为每两行的组合获取这些值。我正在使用
df = read.table('rmatr.txt', header = TRUE, sep = "\t", row.names = 1)
要阅读我的文件也许你可以试试下面的
combn
tmp=do.call(cbind,
sapply(1:(nrow(df)-1),function(i){
sapply((i+1):nrow(df),function(j){
c(i,j,sum(df[i,]==1 & df[j,]==1))
})
})
)
data.frame(
"Row1"=rownames(df)[tmp[1,]],
"Row2"=rownames(df)[tmp[2,]],
"cnt"=tmp[3,]
)
Row1 Row2 cnt
1 A B 0
2 A C 0
3 A D 1
4 A E 1
5 B C 0
6 B D 0
7 B E 2
8 C D 0
9 C E 0
10 D E 1
cbind(
data.frame(t(combn(row.names(df), 2))),
cnt = combn(asplit(df, 1), 2, FUN = function(x) sum(do.call("*", x)))
)
给
X1 X2 cnt
1 A B 0
2 A C 0
3 A D 1
4 A E 1
5 B C 0
6 B D 0
7 B E 2
8 C D 0
9 C E 0
10 D E 1
数据
> dput(df)
structure(list(LA = c(1L, 0L, 0L, 1L, 1L), LE = c(0L, 0L, 0L,
0L, 0L), LI = c(0L, 1L, 0L, 0L, 1L), LO = c(0L, 1L, 0L, 0L, 1L
), LU = c(0L, 1L, 0L, 0L, 0L)), class = "data.frame", row.names = c("A",
"B", "C", "D", "E"))
也许你可以试试下面的
combn
cbind(
data.frame(t(combn(row.names(df), 2))),
cnt = combn(asplit(df, 1), 2, FUN = function(x) sum(do.call("*", x)))
)
给
X1 X2 cnt
1 A B 0
2 A C 0
3 A D 1
4 A E 1
5 B C 0
6 B D 0
7 B E 2
8 C D 0
9 C E 0
10 D E 1
数据
> dput(df)
structure(list(LA = c(1L, 0L, 0L, 1L, 1L), LE = c(0L, 0L, 0L,
0L, 0L), LI = c(0L, 1L, 0L, 0L, 1L), LO = c(0L, 1L, 0L, 0L, 1L
), LU = c(0L, 1L, 0L, 0L, 0L)), class = "data.frame", row.names = c("A",
"B", "C", "D", "E"))
我们还可以从
base R
使用crossprod
out <- as.data.frame.table(tcrossprod(as.matrix(df)))
out[1:2] <- t(apply(out[1:2], 1, sort))
subset(out, Var1 != Var2 & !duplicated(out[1:2]))
# Var1 Var2 Freq
#2 A B 0
#3 A C 0
#4 A D 1
#5 A E 1
#8 B C 0
#9 B D 0
#10 B E 2
#14 C D 0
#15 C E 0
#20 D E 1
out我们也可以使用crossprod
frombase R
out <- as.data.frame.table(tcrossprod(as.matrix(df)))
out[1:2] <- t(apply(out[1:2], 1, sort))
subset(out, Var1 != Var2 & !duplicated(out[1:2]))
# Var1 Var2 Freq
#2 A B 0
#3 A C 0
#4 A D 1
#5 A E 1
#8 B C 0
#9 B D 0
#10 B E 2
#14 C D 0
#15 C E 0
#20 D E 1
嘿,谢谢你的回答!唯一的问题是,当我只想将1计算为匹配项时,它也将0计算为匹配项。。编辑:谢谢@ubuntunoob这个问题我不清楚,我更新了。我会编辑这个问题使它更清楚,即使你已经回答了。多谢各位!嘿,谢谢你的回答!唯一的问题是,当我只想将1计算为匹配项时,它也将0计算为匹配项。。编辑:谢谢@ubuntunoob这个问题我不清楚,我更新了。我会编辑这个问题使它更清楚,即使你已经回答了。多谢各位!嘿我也试过你的答案,它奏效了,而且确实比第一个运行得更快,它还在运行。非常感谢。嘿@ThomasIsCoding,你介意解释一下“sum(do.call(“*”,x)”是如何进行匹配的吗?我不明白为什么它不会只返回行值的和。@ubuntunobx
这里有一个列表,其中包含df
中的两行。当我们执行do.call(“*”,x)
时,我们实际上正在运行x[[1]]*x[[2]]
,这是行的元素乘积。因为行只有二进制值,所以只有当对应的位置都是1
s时,乘积才会给出1
s。然后,我们运行sum
来计算有多少1
s,这表示公共1
s的数量。明白了!谢谢!如果我想div通过“x”中的行的实际总和来计算该值,我可以在“sum(do.call(“*”,x)”之后添加“/(do.call(“+”,x)”吗?@ubuntunob是的,你知道了!我也尝试了你的答案,它工作了,并且确实比第一个运行得更快,这仍然在运行。谢谢你!嘿@thomasscoding,你介意解释一下“sum(do.call(“*”,x)”是如何运行的吗正在进行此匹配吗?我不明白为什么它不会只返回行的值之和。@ubuntunobx
这里有一个列表,其中包含df
中的两行。当我们执行do.call(“*”,x)
时,我们实际上正在运行x[[1]*x[[2]]
,这是行的元素乘积。因为行只有二进制值,所以只有当对应的位置都是1
s时,乘积才会给出1
s。然后,我们运行sum
来计算有多少1
s,这表示公共1
s的数量。明白了!谢谢!如果我想div通过“x”中的行的实际总和来计算该值,我可以在“sum(do.call(“*”,x)”之后添加“/(do.call(“+”,x)”吗?@ubuntunob是的,您知道了