2014-05-06 2 views
5

У меня есть кадр данных, как это:Как я могу Транспонирование таблицы в матрицу

n1 n2 freq 
A  B  10 
W  Q  9 
A  E  23 
A  F  31 
A  W  9 
B  Q  25 
B  E  54 
B  F  33 
B  W  14 
A  Q  4 
F  E  1 
E  W  43 
Q  E  67 
F  W  10 
Q  F  6 

Как я могу перенести данные в матрицу, как это?

 A B E F W Q 
A 1 10 23 31 9 4 
B 10 1 54 33 14 25 
E 23 54 1 1 43 67 
F 31 33 1 1 10 6 
W 9 14 43 10 1 9 
Q 4 25 67 6 9 1 

diag(data) <- 1

+0

Я хотел бы избежать использования термина " transpose "для этой задачи, поскольку это конкретная операция матрицы. Она заполняет симметричную матрицу из разреженного представления –

ответ

0

Использование уровней фактора в качестве индексов к матричным назначение:

dat <- read.table(text="n1 n2 freq 
A  B  10 
W  Q  9 
A  E  23 
A  F  31 
A  W  9 
B  Q  25 
B  E  54 
B  F  33 
B  W  14 
A  Q  4 
F  E  1 
E  W  43 
Q  E  67 
F  W  10 
Q  F  6", header=TRUE, stringsAsFactors=FALSE) 

levs <- sort(unique(c(dat$n1,dat$n2))) 
dat$n1 <- factor(dat$n1, levels=levs) 
dat$n2 <- factor(dat$n2, levels=levs) 
M <- matrix(1, nrow=length(levs), ncol=length(levs)) 
M[with(dat, cbind(n1,n2))] <- dat$freq # Mostly the upper triangle, save 3. 

> M 
    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 1 10 23 31 4 9 
[2,] 1 1 54 33 25 14 
[3,] 1 1 1 1 1 43 
[4,] 1 1 1 1 1 10 
[5,] 1 1 67 6 1 1 
[6,] 1 1 1 1 9 1 

M[with(dat, cbind(n2,n1))] <- dat$freq # The mirror image 
dimnames(M) <- list(levs,levs) 
#------- 
> M 
    A B E F Q W 
A 1 10 23 31 4 9 
B 10 1 54 33 25 14 
E 23 54 1 1 67 43 
F 31 33 1 1 6 10 
Q 4 25 67 6 1 9 
W 9 14 43 10 9 1 
1
DF 
## n1 n2 freq 
## 1 A B 10 
## 2 W Q 9 
## 3 A E 23 
## 4 A F 31 
## 5 A W 9 
## 6 B Q 25 
## 7 B E 54 
## 8 B F 33 
## 9 B W 14 
## 10 A Q 4 
## 11 F E 1 
## 12 E W 43 
## 13 Q E 67 
## 14 F W 10 
## 15 Q F 6 

N <- sort(unique(unlist(DF[, 1:2]))) 
N 
## [1] "A" "B" "E" "F" "Q" "W" 

# First we create empty matrix with dims of expected result 
RES <- matrix(NA, nrow = length(N), ncol = length(N), dimnames = list(N, N)) 


# now lets populate the matrix 
RES[as.matrix(DF[, 1:2])] <- DF[, 3] 
# We repeat the step with coordinates inverted. note 1:2 vs 2:1 As the matrix is supposed to be symmetric 
RES[as.matrix(DF[, 2:1])] <- DF[, 3] 
# Set diagonal to 1 
RES[cbind(N, N)] <- 1 
# expected result 
RES 
## A B E F Q W 
## A 1 10 23 31 4 9 
## B 10 1 54 33 25 14 
## E 23 54 1 1 67 43 
## F 31 33 1 1 6 10 
## Q 4 25 67 6 1 9 
## W 9 14 43 10 9 1 
0
df # your data frame  

mnames <- sort(unique(as.character(df$n1))) 

mdim <- length(mnames) 

m <- matrix(1,nrow=mdim,ncol=mdim,dimnames=list(mnames,mnames)) 

apply(df, 1, function(x) { m[ x['n1'], x['n2'] ] <<- x['freq'] 
          m[ x['n2'], x['n1'] ] <<- x['freq'] }) 

m <- apply(m,1:2,as.integer) 

m 

#  A B E F Q W 
# A 1 10 23 31 4 9 
# B 10 1 54 33 25 14 
# E 23 54 1 1 67 43 
# F 31 33 1 1 6 10 
# Q 4 25 67 6 1 9 
# W 9 14 43 10 9 1 
2

Вот альтернативный подход.

Предполагая, что вы начинаете с data.frame названием «mydf», вы можете попробовать:

## The "n" columns 
Cols <- c("n1", "n2") 

## The factor levels 
Levs <- sort(unique(unlist(mydf[Cols]))) 

## Applying the factor levels to all "n" columns 
mydf[Cols] <- lapply(mydf[Cols], function(x) factor(x, Levs)) 

## xtabs is your friend 
out <- xtabs(freq ~ n1 + n2, mydf) 
out <- out + t(out) 

## replace the diagonal 
diag(out) <- 1 
out 
# n2 
# n1 A B E F Q W 
# A 1 10 23 31 4 9 
# B 10 1 54 33 25 14 
# E 23 54 1 1 67 43 
# F 31 33 1 1 6 10 
# Q 4 25 67 6 1 9 
# W 9 14 43 10 9 1 
Смежные вопросы