3

R newbie. I am trying to create a co-occurrence matrix with horizontal data. I want to know which elements co-occur 'TRUE' together in rows.

Each row represents an article. Each article has many true/false variables marking the presence or lack of an element. There are 100 elements, abbreviated here, and over 10k of articles. So a 10,000 x 101 data frame.

 dat <- read.table(text='"article"     "element1"   "element2"   "element3"   "element4"
 1     "a house a home"     "TRUE"   "TRUE"   "FALSE"   "FALSE"
 2     "cabin in the woods"     "TRUE"   "TRUE" "FALSE" "FALSE"
 3     "motel is a hotel"   "TRUE"    "FALSE"   "TRUE"   "FALSE"', header=TRUE)

I tried following this co-occurrence question (Creating co-occurrence matrix), but it seems like since the data is organized differently, that approach wont work.

What would be helpful would be a matrix if 100 elements x 100 elements. Anyone have suggestions?

Community
  • 1
  • 1
lmcshane
  • 1,074
  • 4
  • 14
  • 27

2 Answers2

6

The sparse matrix answer in the question you linked gives a fast, easy way to do this. It is (somewhat) easier to do with your data structure.

# Make a vector of all elements.
elems <- colnames(dat)[-1] 
# Make a sparse matrix
library(Matrix)
s <- Matrix(as.matrix(dat[elems]), sparse=TRUE, dimnames=list(dat$article,elems))
# calculate co-occurrences
(t(s) %*% s)
# 4 x 4 sparse Matrix of class "dgCMatrix"
#          element1 element2 element3 element4
# element1        3        2        1        .
# element2        2        2        .        .
# element3        1        .        1        .
# element4        .        .        .        .

# If you don't want the exact number, and you want a "dense" matrix
as.matrix((t(s) %*% s) >= 1)
#          element1 element2 element3 element4
# element1     TRUE     TRUE     TRUE    FALSE
# element2     TRUE     TRUE    FALSE    FALSE
# element3     TRUE    FALSE     TRUE    FALSE
# element4    FALSE    FALSE    FALSE    FALSE
Community
  • 1
  • 1
nograpes
  • 18,623
  • 1
  • 44
  • 67
4

This seems pretty quick:

mat <- matrix(0,ncol=ncol(dat[-1]),nrow=ncol(dat[-1]))
res <- combn(colnames(dat[-1]), 2, 
             FUN=function(x) sum(pmin(dat[x[1]],dat[x[2]])==1) )
mat[lower.tri(mat)] <- res
mat[upper.tri(mat)] <- res
mat

#     [,1] [,2] [,3] [,4]
#[1,]    0    2    1    0
#[2,]    2    0    0    0
#[3,]    1    0    0    0
#[4,]    0    0    0    0
thelatemail
  • 91,185
  • 12
  • 128
  • 188