我如何将表转置为矩阵

时间:2014-05-06 06:28:54

标签: r

我有一个数据框,如下所示:

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

4 个答案:

答案 0 :(得分:2)

这是另一种方法。

假设您开始使用名为“mydf”的data.frame,您可以尝试:

## 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

答案 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

答案 2 :(得分: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

答案 3 :(得分: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