2012-10-10 12 views
8

Tengo lo que debería ser un problema de remodelación simple, pero no puedo resolverlo. Parte de mis datos es el siguiente:Remodelando el marco de datos con duplicados

foo <- structure(list(grade = c(3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 
3, 3, 4, 4, 5, 5, 6, 6), var.type = structure(c(3L, 2L, 3L, 2L, 
3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L, 3L, 2L 
), .Label = c("Raw Score", "SE", "SS"), class = "factor"), var.val = c(120L, 
47L, 120L, 46L, 120L, 46L, 120L, 47L, 120L, 46L, 120L, 46L, 120L, 
12L, 120L, 14L, 120L, 16L, 120L, 20L)), .Names = c("grade", "var.type", 
"var.val"), row.names = c(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 
11L, 12L, 13L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L), class = "data.frame") 

o

grade var.type var.val 
2  3  SS  120 
3  3  SE  47 
4  4  SS  120 
5  4  SE  46 
6  5  SS  120 
7  5  SE  46 

quiero que se vea como esto:

grade SS SE 
3  120 47 
4  120 46 
5  120 46 

y así sucesivamente. He intentado remodelar, fundido, y dcast como en este hilo:

Reshaping dataset

pero nada parece funcionar. Realmente agradecería algo de ayuda. TIA.

+2

En el ejemplo de los datos que nos ha proporcionado anteriormente, existe una fila con ('grade', 'var.type',' var.val') = (3, SE, 47), así como uno con (3, SE, 12). ¿Qué 'var.val' quieres que aparezca en la columna' SE' de salida? –

+0

Oh, lo siento. Lo arruiné. Parece que hay otra variable que necesito agregar. Nueces. Más complicado de lo que pensé. – Stuart

+0

Simplemente actualice la pregunta con los nuevos datos. – Maiasaura

Respuesta

7

Si quiere remodelar y has duplicados, vas a tener que dar a cada pareja un identificador único:

foorle <- rle(foo$grade) 
fooids <- rep(seq_len(length(foorle$values)), times=foorle$lengths) 

fooids 
[1] 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 

Ahora usted será capaz de utilizar adecuadamente remodelar:

idfoo <- cbind(id=fooids, foo) 

library(reshape) 
dcast(idfoo, id+grade~var.type, value.var="var.val") 

    id grade SE SS 
1 1  3 47 120 
2 2  4 46 120 
3 3  5 46 120 
4 4  6 47 120 
5 5  7 46 120 
6 6  8 46 120 
7 7  3 12 120 
8 8  4 14 120 
9 9  5 16 120 
10 10  6 20 120 

EDITAR: Tenga en cuenta que estoy suponiendo que sus datos están en orden, de lo contrario tendrá problemas para distinguir entre los duplicados. Si no lo es, siempre puede usar order para que así sea.

+1

También recomiendo [esta respuesta] (http://stackoverflow.com/a/12831856/1465387) a una pregunta similar que creo que tiene un enfoque mejor que el mío. –

2

No es tan bonita como cambio de forma, pero

data.frame(grade = foo[2 * (1:(nrow(foo)/2)),]$grade, 
      SS = foo[foo$var.type == "SS", ]$var.val, 
      SE = foo[foo$var.type == "SE", ]$var.val) 

produce

grade SS SE 
1  3 120 47 
2  4 120 46 
3  5 120 46 
4  6 120 47 
5  7 120 46 
6  8 120 46 
7  3 120 12 
8  4 120 14 
9  5 120 16 
10  6 120 20 

Hay que asumir los datos provienen de pares de filas de este.

4
library(plyr) 
library(reshape2) 
# First we add a grouping variable to deal with the duplicates 
foo <- ddply(foo, .(grade, var.type), function(x) { x$group <- 1:nrow(x); x }) 
dcast(foo, grade + group ~ var.type, value.var= "var.val")[-2] 

grade SE SS 
1  3 47 120 
2  3 12 120 
3  4 46 120 
4  4 14 120 
5  5 46 120 
6  5 16 120 
7  6 47 120 
8  6 20 120 
9  7 46 120 
10  8 46 120 
0

Si no tiene ningún duplicados, esto va a funcionar muy bien:

ss <- subset(foo, var.type=='SS') 
se <- subset(foo, var.type=='SE') 
ss <- data.frame(grade=ss$grade,SS=ss$var.val) 
se <- data.frame(grade=se$grade,SE=se$var.val) 
bar <- merge(ss,se,by='grade') 
Cuestiones relacionadas