2017-04-27 51 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