2017-04-27 21 views
3

我有data.frame,看起来像这样:相同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与其余:

  • A对B:0(因为它们具有0共同的要素)
  • A对C:1(在共同c)中
  • A对d:2(p和S中常见)
  • A对E:3-(p, w,a,共同)

然后相同:B对C,D,E列等。

任何人都可以帮助我吗?我不知道如何实现这一点。

回答

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部分也与RcppEigenhere这将使这个更快

+1

非常感谢你akrun。它完美的工作! – Bfu38

1

另一种方法是使用combn两次,一次获得列组合,然后找到元素相交的长度。

cbind.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