2015-04-14 17 views
8

Sono relativamente nuovo a R, quindi perdonami per quello che ritengo essere una domanda relativamente semplice.Matrice di generazione e somma

Ho dati in forma

1 2 3 4 5 
A 0 1 1 0 0 
B 1 0 1 0 1 
C 0 1 0 1 0 
D 1 0 0 0 0 
E 0 0 0 0 1 

dove A-E sono persone e 1-5 sono i binari di se o non hanno questa qualità. Devo creare una matrice di A-E in cui cella A, B = 1 se la somma di qualsiasi qualità 1-5 per A & B somma a 2. (Se condividono almeno una qualità). Il 5x5 semplice sarebbe:

A B C D E 
A 1    
B 1 1   
C 1 0 1  
D 0 1 0 1 
E 0 1 0 0 1 

Ho quindi bisogno di sommare l'intera matrice. (Sopra dovrebbe essere 9). Ho migliaia di osservazioni, quindi non posso farlo a mano. Sono sicuro che ci sono poche righe di codice, non ho abbastanza esperienza.

Grazie!

MODIFICA: Ho importato i dati da un file .csv con le colonne (1-5 sopra) come variabili, nei dati reali ho 40 variabili. A-E sono osservazioni ID uniche di persone, circa 2000. Vorrei anche sapere come convertire prima questo in una matrice, al fine di eseguire le grandi risposte che hai già fornito. Grazie!

risposta

6

È possibile utilizzare la moltiplicazione di matrici qui

out <- tcrossprod(m) 
# A B C D E 
# A 2 1 1 0 0 
# B 1 3 0 1 1 
# C 1 0 2 0 0 
# D 0 1 0 1 0 
# E 0 1 0 0 1 

Quindi impostare il diagonale a uno, se necessario

diag(out) <- 1 

Come Davida sottolinea nei commenti tcrossprod è una sostanza che fa m %*% t(m)

diversi modi per calcolare le loro sum l ecco uno

sum(out[upper.tri(out, diag=TRUE)] , na.rm=TRUE) 
+0

Grazie! Capisco questo, e dovrebbe funzionare, ma devo fare una domanda più facile, ho i dati ora come variabili. Come posso cambiarlo in una matrice senza dover digitare tutti i numeri? – ChrisDH

+0

Prego. Se hai ciascuna riga puoi usare 'rbind' per unirli tutti insieme e formerà una' matrice '. Altrimenti, se i tuoi dati sono un 'data.frame' puoi usare' as.matrix'. Se uno di questi non funziona, puoi aggiungere una piccola modifica alla tua domanda che mostra come sono archiviati i dati, grazie – user20650

+0

Grazie, ho aggiunto la modifica sopra. Ho importato i dati da un file .csv con le colonne (1-5 sopra) come variabili, nei dati reali ho 40 variabili. A-E sono osservazioni ID uniche di persone, circa 2000. Vorrei anche sapere come convertire prima questo in una matrice, al fine di eseguire le grandi risposte che hai già fornito. – ChrisDH

1

è possibile utilizzare outer, se m è il vostro matrice quadrata:

f = Vectorize(function(u,v) any(colSums(m[c(u,v),])>1)+0L) 

res = outer(1:ncol(m), 1:ncol(m), FUN=f) 
colnames(res) = row.names(res) = rownames(m) 

# A B C D E 
#A 1 1 1 0 0 
#B 1 1 0 1 1 
#C 1 0 1 0 0 
#D 0 1 0 1 0 
#E 0 1 0 0 1 

dati:

m = structure(c(0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 
1, 0, 0, 0, 1, 0, 0, 1), .Dim = c(5L, 5L), .Dimnames = list(c("A", 
"B", "C", "D", "E"), NULL)) 
1

Che dire di questo? (di cortesia non elegante come la soluzione tcrossprod):

d <- dim(m) 
ind <- expand.grid(1:d[1],1:d[1]) 
M <- matrix(as.numeric(apply(cbind(m[ind[,2],],m[ind[,1]]), 1, 
+ function(x) sum(x[1:d[1]] == 1 & x[(d[1]+1):(d[1]*2)] == 1) >=1)), ncol = d[1]) 

rownames(M) = colnames(M) = rownames(m) 
M 
    A B C D E 
A 1 1 1 0 0 
B 1 1 0 1 1 
C 1 0 1 0 0 
D 0 1 0 1 0 
E 0 1 0 0 1 
Problemi correlati