2012-10-10 6 views
8

Ich habe, was ein einfaches Umformproblem sein sollte, aber ich kann es nicht herausfinden. Ein Teil meiner Daten sieht wie folgt aus:Datenrahmen mit Duplikaten umformen

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") 

oder

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 

Ich möchte es so aussehen:

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

und so weiter. Ich habe versucht, reshape, gegossen, und dcast wie in diesem Thread:

Reshaping dataset

aber nichts scheint zu funktionieren. Ich würde wirklich etwas Hilfe schätzen. TIA.

+2

Im Beispiel Daten, die Sie uns oben gegeben haben, gibt es eine Reihe mit ('grade' ist, 'var.type',' var.val') = (3, SE, 47), sowie eins mit (3, SE, 12). Welches 'var.val' wollen Sie in der Ausgabe' SE' Spalte sehen? –

+0

Oh, Entschuldigung. Ich vermasselte. Es scheint, dass es eine weitere Variable gibt, die ich hinzufügen muss. Nüsse. Komplizierter als ich. – Stuart

+0

Aktualisieren Sie einfach die Frage mit den neuen Daten. – Maiasaura

Antwort

7

Wenn Sie möchten, neu zu gestalten und Sie Duplikate, Sie gehen zu müssen jedes Paar eine eindeutige ID geben:

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 

Jetzt werden Sie in der Lage, richtig zu verwenden umformen:

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 

EDIT: Bitte beachten Sie, dass Ihre Daten in Ordnung sind, sonst haben Sie Probleme, zwischen Duplikaten zu unterscheiden. Wenn nicht, können Sie immer order verwenden, so dass es ist.

+1

Ich empfehle auch [diese Antwort] (http://Stackoverflow.com/a/12831856/1465387) zu einer ähnlichen Frage, die meiner Meinung nach einen besseren Ansatz hat als meiner. –

2

Es ist nicht so hübsch wie reshape, aber

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) 

produziert

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 

Sie haben die Daten zu übernehmen in Paaren von Reihen für diese kommt.

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

Wenn Sie nicht haben keine Duplikate, wird dies gut funktionieren:

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')