2015-07-29 7 views
5

Ich möchte einen Dataframe von Long Format in ein Wide Format konvertieren, aber mit ungleichen Gruppengrößen.Konvertiere R Dataform von Long zu Wide Format, aber mit ungleichen Gruppengrößen, zur Verwendung mit qcc

Die eventuelle Verwendung wird in 'qcc' sein, die einen Datenrahmen oder eine Matrix erfordert, wobei jede Zeile aus einer Gruppe besteht, wobei NAs in Gruppen verwendet werden, die weniger Abtastwerte haben.

Der folgende Code erstellt ein Beispieldatenset und zeigt die manuelle Konvertierung in das gewünschte Format an.

# This is an example of the initial data that I have 
# * 10 sample measurements, over 3 groups with 3, 2, and 5 elements respectively 
x <- rnorm(10) 
x_df <- data.frame(time = c(rep('2001 Q1',3), rep('2001 Q2',2), rep('2001 Q3',5)), measure = x) 
x_df 

# This is a manual conversion into the desired format 
x_pad <- c(x[1:3], NA, NA, x[4:5], NA, NA, NA, x[6:10]) 
x_matrix <- matrix(x_pad, nrow = 3, ncol = 5, byrow = TRUE, dimnames = list(c('2001 Q1','2001 Q2','2001 Q3'))) 
x_matrix # desired format 

# An example of how it will be used 
library(qcc) 
plot(qcc(x_matrix, type = 'xbar', plot = FALSE)) 

So, würde Ich mag diese konvertieren:

 time  measure 
1 2001 Q1 0.14680685 
2 2001 Q1 0.53593193 
3 2001 Q1 0.56097974 
4 2001 Q2 -1.48102689 
5 2001 Q2 0.18150972 
6 2001 Q3 1.72018147 
7 2001 Q3 -0.08480855 
8 2001 Q3 -2.23208877 
9 2001 Q3 -1.15269107 
10 2001 Q3 0.57975023 

... dazu ...

   [,1]  [,2]  [,3]  [,4]  [,5] 
2001 Q1 0.1468068 0.53593193 0.5609797  NA  NA 
2001 Q2 -1.4810269 0.18150972   NA  NA  NA 
2001 Q3 1.7201815 -0.08480855 -2.2320888 -1.152691 0.5797502 

Es gibt wohl eine einfache Möglichkeit (vielleicht einige Nutzung von umformen oder umformen, das mir nicht bekannt ist?), aber eine Menge Suchen hat mir bisher nicht geholfen.

Danke für jede Hilfe!

==========

Von einem der folgenden Lösungen, generiert die nach dem letzten qcc xbar Grundstück, einschließlich Gruppen Etiketten:

library(splitstackshape) 
out_df <- dcast(getanID(x_df, 'time'), time~.id, value.var='measure') 
qcc(out_df[,-1], type = 'xbar', labels = out_df[,1]) 

Antwort

6

Sie eine Sequenz Spalte erstellen (‚.id‘) mit getanID von splitstackshape und verwenden dcast von data.table das lange Format Wide-Format zu konvertieren. Die Ausgabe von splitstackshape ist eine data.table. Wenn wir splitstackshape laden, wird data.table ebenfalls geladen. Wenn Sie also bereits die devel-Version von data.table haben, können Sie auch die dcast von data.table verwenden.

library(splitstackshape) 
dcast(getanID(df1, 'time'), time~.id, value.var='measure') 
#  time   1   2   3   4   5 
#1: 2001 Q1 0.1468068 0.53593193 0.5609797  NA  NA 
#2: 2001 Q2 -1.4810269 0.18150972   NA  NA  NA 
#3: 2001 Q3 1.7201815 -0.08480855 -2.2320888 -1.152691 0.5797502 
+0

Ich mag diese Lösung insbesondere, weil sie übersichtlich ist und weil sie sie als Datenframe hält. 'qcc' scheint Datentabellen nicht sehr zu mögen. Nicht sicher, ob es richtige StackOverflow-Etikette ist, aber ich werde meine Frage bearbeiten, um einzuschließen, wie man die obige Lösung im actuall qcc-Plotten auch verwendet, falls jemand diese Frage auf der Suche nach qcc-Lösungen findet. –

+0

@JChou Wenn Sie die Ausgabe in 'dat.frame' konvertieren möchten, können Sie' setDF (res) 'verwenden, wobei' res <- dcast (getanID (... ' – akrun

+0

Danke, super! Ich machte ein ganzes Eine Menge von as.data.frame() - Konvertierungen in den Datentabellen. Um ehrlich zu sein, muss ich nur über Datentabellen lernen! (Ich bin relativ neu in R im Allgemeinen). –

6

Sie benötigen eine Zwischenvariable, die eine ID "innerhalb der Zeit" ergibt. Sie können es schaffen und neu zu gestalten, wie dies

library(tidyr) 
library(dplyr) 

group_by(X, time) %>% 
    mutate(seq = 1:n()) %>% 
    ungroup() %>% 
    spread(seq, measure) 
+0

Es gibt auch eine 'row_number()', die auch nützlich sein kann. – akrun

+0

Das hat mich gerettet! Ich hatte keine Ahnung, dass ich 'ungroup()' zwischen 'group_by()' und 'spread()' verwenden musste. Weißt du, warum das notwendig ist? – Leo

+0

Ehrlich gesagt, ich weiß nicht, ob Sie _have_ haben. Ich habe nur eine zwanghafte Angewohnheit, meine Daten zu gruppieren, es sei denn, ich habe einen Grund, in nachfolgenden Befehlen in Gruppen zu bleiben. Ich bekomme die gleichen Ergebnisse mit dieser Datenprobe, egal ob ich mich entgleise oder nicht. – Benjamin

5

Ein weiterer splitstackshape Ansatz

cSplit(setDT(df)[, toString(measure), by='time'], 'V1', ',') 

#  time  V1_1  V1_2  V1_3  V1_4  V1_5 
#1: 2001 Q1 0.1468068 0.53593193 0.5609797  NA  NA 
#2: 2001 Q2 -1.4810269 0.18150972   NA  NA  NA 
#3: 2001 Q3 1.7201815 -0.08480855 -2.2320888 -1.152691 0.5797502 

Oder mit der devel Version von data.table ein ähnlicher Ansatz nach der ‚Maßnahme‘ Einfügen zusammen mit der Gruppierung Spalte ‚Zeit‘ wäre tstrsplit mit dem ‚V1 aufzuspalten 'Spalte generiert von toString(measure).

setDT(df)[, toString(measure), by ='time'][, c(list(time), tstrsplit(V1, ', '))] 

Auch wir können type.convert=TRUE in tstrsplit fügen Sie die class der geteilten Spalten zu konvertieren. Standardmäßig ist es FALSE.

+1

Das ist ein niedlicher Weg. – akrun

+0

Danke @akrun :) Ich glaube, ich habe diesen Weg aus einer deiner alten Antworten kennengelernt –

+1

Mit der Devel-Version kannst du auch 'tstrsplit' verwenden, etwas wie' setDT (df1) [, toString (measure), by = 'time'] [, c (Liste (Zeit), tstrsplit (V1, ','))] ' – akrun

Verwandte Themen