I have a data set with three columns.
X = c("x", "y", "z", "x", "y", "w")
Y = c("a", "b", "c" , "b", "a", "c")
set.seed(3)
Z = sample(10,6)
dat = data.frame(X, Y, Z)
The dat looks like
X Y Z
1 x a 2
2 y b 8
3 z c 4
4 x b 3
5 y a 9
6 w c 6
I want to transform the above data into the format that the rows are X and the columns are Y and the values in the matrix are Z. Essentially I want the following:
a b c
x 2 3 0
y 9 8 0
z 0 0 4
w 0 0 6
This is somewhat similar to edge list to adjacency matrix, except the data matrix is not square. Please help. Thanks!
Try
library(reshape2)
acast(dat, X~Y, value.var='Z', fill=0)
To get the rows in order as the expected result
acast(dat, factor(X, levels=unique(X))~Y, value.var='Z', fill=0)
Or as @thelatemail commented
xtabs(Z~X+Y, data= dat)[unique(dat$X),]
Or a modified version if both columns are not in order
with(dat, xtabs(Z ~ X + Y)[unique(X), unique(Y)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With