我有一个看起来像这样的data.frame:
> DF1
A B C D E
a x c h p
c d q t w
s e r p a
w l t s i
p i y a f
我想将data.frame的每一列与其余列进行比较,以计算公共元素的数量。例如,我想将列A与所有剩余列(B,C,D,E)进行比较,并以这种方式计算公共实体:
A与剩下的:
然后相同:B与C,D,E列等。
有人能帮帮我吗?我不知道如何实现这一点。
答案 0 :(得分:3)
我们可以遍历列名并与其他列进行比较,方法是intersect
并获取length
sapply(names(DF1), function(x) {
x1 <- lengths(Map(intersect, DF1[setdiff(names(DF1), x)], DF1[x]))
c(x1, setNames(0, setdiff(names(DF1), names(x1))))[names(DF1)]})
# A B C D E
#A 0 0 1 3 3
#B 0 0 0 0 1
#C 1 0 0 1 0
#D 3 0 1 0 2
#E 3 1 0 2 0
或者这可以通过在获得长格式化(melt
)数据集的频率后获取十字产品来更紧凑地完成
library(reshape2)
tcrossprod(table(melt(as.matrix(DF1))[-1])) * !diag(5)
# Var2
#Var2 A B C D E
# A 0 0 1 3 3
# B 0 0 0 0 1
# C 1 0 0 1 0
# D 3 0 1 0 2
# E 3 1 0 2 0
注意:crossprod
部分也通过RcppEigen
here实施,这样可以加快速度
答案 1 :(得分:1)
另一种方法是使用combn
两次,一次获取列组合,然后查找元素交叉点的长度。
cbind.data.frame
返回data.frame,setNames
用于添加列名。
setNames(cbind.data.frame(t(combn(names(df), 2)),
combn(names(df), 2, function(x) length(intersect(df[, x[1]], df[, x[2]])))),
c("col1", "col2", "count"))
col1 col2 count
1 A B 0
2 A C 1
3 A D 3
4 A E 3
5 B C 0
6 B D 0
7 B E 1
8 C D 1
9 C E 0
10 D E 2