Pergunta

Let's say I have a data.frame with three rows: x, y, and f(x,y). The x and y are gridded at integer values (i.e. indices to a matrix). Is there a clean way in R to from this three column thing to a matrix of f(x,y) values in which each entry corresponds to the (x,y,f(x,y)) triplet I had before? I'd like to avoid doing a for-loop, although that is of course an easy option.

I.e. if that wasn't clear, I'd like to go from:

x, y, f.x_y;
1, 1, 3.1;
1, 2, 35.5;
1, 3, 4.4;
2, 1, 3.1; 
2, 2, 3.3;
2, 3, 5.5;
3, 1, 24.1;
3, 2, 3.14;
3, 3, 3.55;

---- To -----

3.1, 3.1, 24.1;   
35.5, 3.3, 3.14;
4.4, 5.5, 3.55 
Foi útil?

Solução

Here are four options to consider.

In base R:

reshape(mydf, direction = "wide", idvar="x", timevar="y")
#   x f.x_y.1 f.x_y.2 f.x_y.3
# 1 1     3.1   35.50    4.40
# 4 2     3.1    3.30    5.50
# 7 3    24.1    3.14    3.55

xtabs(f.x_y ~ x + y, mydf)
#    y
# x       1     2     3
#   1  3.10 35.50  4.40
#   2  3.10  3.30  5.50
#   3 24.10  3.14  3.55

unstack(mydf, f.x_y ~ y)
#     X1    X2   X3
# 1  3.1 35.50 4.40
# 2  3.1  3.30 5.50
# 3 24.1  3.14 3.55

Using the "reshape2" package:

library(reshape2)
dcast(mydf, x ~ y, value.var="f.x_y")
#   x    1     2    3
# 1 1  3.1 35.50 4.40
# 2 2  3.1  3.30 5.50
# 3 3 24.1  3.14 3.55

This assumes a data.frame like this as your source data:

mydf <- data.frame(x = rep(1:3, each = 3),
                   y = rep(1:3, times = 3),
                   f.x_y = c(3.1, 35.5, 4.4, 3.1, 3.3, 
                             5.5, 24.1, 3.14, 3.55))
mydf
#   x y f.x_y
# 1 1 1  3.10
# 2 1 2 35.50
# 3 1 3  4.40
# 4 2 1  3.10
# 5 2 2  3.30
# 6 2 3  5.50
# 7 3 1 24.10
# 8 3 2  3.14
# 9 3 3  3.55

Outras dicas

An alternative using @Ananda's example data:

m <- with(mydf, matrix(NA, nrow=max(x), ncol=max(y) ) 
m[as.matrix(mydf[1:2])] <- mydf$f.x_y
m

#     [,1]  [,2] [,3]
#[1,]  3.1 35.50 4.40
#[2,]  3.1  3.30 5.50
#[3,] 24.1  3.14 3.55
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top