Транспонировать данные по группам в R

У меня есть данные в следующей структуре:

x <- read.table(header=T, text="
X Y D S
a e 1 10
a e 2 20
a f 1 50
b c 1 40
b c 2 30
b c 3 60
b d 1 10 
b d 2 20")

И я хочу получить следующий результат:

X Y   1   2   3
a e  10  20
a f  50
b c  40  30  60
b d  10  20

Для каждой комбинации столбцов X и Y я хотел бы перенести данные в столбце S по порядку в столбце D.

Я думал, что xtabs() будет работать, но я так не думаю, мой лучший вариант:

xtabs(formula=S~Y+D,data=x)

С результатом:

   D
Y    1  2  3
  c 40 30 60
  d 10 20  0
  e 10 20  0
  f 50  0  0

person Tomas Greif    schedule 29.06.2013    source источник


Ответы (3)


require(reshape2)
dcast(x, X + Y ~ D, value.var="S")

Если вы хотите заполнить пустые записи 0 вместо NA (по умолчанию), то

dcast(x, X + Y ~ D, value.var="S", fill=0)
person Arun    schedule 29.06.2013

Решение в базе R:

> reshape(x, timevar="D", idvar=c("X","Y"), direction="wide")
  X Y S.1 S.2 S.3
1 a e  10  20  NA
3 a f  50  NA  NA
4 b c  40  30  60
7 b d  10  20  NA
person Ferdinand.kraft    schedule 29.06.2013

Два других ответа очень хороши, но как бы то ни было, поскольку вы упомянули, что начали свои попытки с xtabs, вы можете приблизиться к тому, что искали, с помощью сочетание xtabs и ftable. Однако результат будет включать все уровни фактора

ftable(xtabs(S ~ ., x))
#     D  1  2  3
# X Y           
# a c    0  0  0
#   d    0  0  0
#   e   10 20  0
#   f   50  0  0
# b c   40 30 60
#   d   10 20  0
#   e    0  0  0
#   f    0  0  0

В качестве альтернативы вы можете сделать что-то вроде этого:

data.frame(unique(x[1:2]), 
           as.data.frame.matrix(xtabs(S ~ do.call(paste, x[1:2]) + D, x)))
#   X Y X1 X2 X3
# 1 a e 10 20  0
# 3 a f 50  0  0
# 4 b c 40 30 60
# 7 b d 10 20  0
person A5C1D2H2I1M1N2O1R2T1    schedule 10.07.2013