我有一个数据框,如下所示:
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 :(得分: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