2016-10-31 7 views
1

Ich versuche, einen neuen Datenrahmen zu erstellen, der eine verkürzte Version einer Reihe von Vektoren ist.Mittel von Vektoren in Datenrahmen von Faktor

während meine Daten aufgebaut ist so etwas wie

mat <- matrix(1:18, 6) 
g <- c("a", "a", "b", "b", "c", "c") 
df <- cbind(g, mat) 

Ich mag würde

result_df wie

a 1.5 7.5 13.5 
b 3.5 9.5 15.5 
c 5.5 11.5 17.5 

ich in Schwierigkeiten bin mit erreichen, wenn ich die for-Schleife versuchen, gibt es Ein Weg lapply() oder apply() kann dies nativ tun? Gibt es eine einfachere Lösung?

+0

Sie wollen mit einem Datenrahmen beginnen statt eine Matrix. –

+0

genial. meine Daten sind in einem Datenrahmen, ich werde dies versuchen .. danke @Zhenyuan Li – c0ba1t

+0

@ZiaRanks - Nun, Ihr Beispiel ist nicht –

Antwort

2

Eine weitere Option, die für zukünftige Anforderungen flexibler sein könnte, ist dplyr. Dies erfordert, dass die Daten in einem dat.frame liegen, aber es klingt wie das, was Sie sowieso haben.

df <- data.frame(g, mat) 

df %>% 
    group_by(g) %>% 
    summarise_all(mean) 

Es Gruppen durch die g Säule, nimmt dann einen Mittelwert aller der verbleibenden Spalten. Es gibt zurück:

 g X1 X2 X3 
1  a 1.5 7.5 13.5 
2  b 3.5 9.5 15.5 
3  c 5.5 11.5 17.5 

Welche ich glaube, ist Ihr gewünschtes Ergebnis. Wenn mit tidyr kombiniert, kann es auch leichter machen, es zu benutzen/diese Mittel zugreifen, indem sie in einem langen Format

df %>% 
    gather(Measurement, Value, -g) %>% 
    group_by(g, Measurement) %>% 
    summarise(mean = mean(Value)) 

Rückkehr setzen:

 g Measurement mean 
1  a   X1 1.5 
2  a   X2 7.5 
3  a   X3 13.5 
4  b   X1 3.5 
5  b   X2 9.5 
6  b   X3 15.5 
7  c   X1 5.5 
8  c   X2 11.5 
9  c   X3 17.5 
+0

Es gibt 2151 Werte, also wird es wirklich lang, aber das sind sehr gute Lösungen. Danke @MarkPeterson – c0ba1t

+0

In diesem Fall kann "wirklich lang" tatsächlich die Dinge einfacher machen. Bei so vielen Werten schaust du es wahrscheinlich sowieso nicht oft an. Viele Plotting-Ansätze, insbesondere 'ggplot2', arbeiten mit langen Daten einfacher. In ähnlicher Weise können ähnliche Messtypen einfacher erfasst werden, insbesondere wenn die Namen der Werte ähnlich sind. –

+0

Das ist was ich lese. Ich lerne immer noch das Schmelz- und Guss-Zeug ... – c0ba1t

1

Ich habe zwei Optionen, je nachdem, ob Sie zuerst die Zeilenoperation oder die Spaltenoperation ausführen möchten.

Die Option "column-first" durchläuft alle Spalten unter Verwendung von lapply und verwendet dann tapply, um für jede Spalte den Mittelwert nach Gruppe zu finden.

as.data.frame(lapply(dat, tapply, INDEX = g, mean)) 

Die Zeilen ersten Option wird der Datenrahmen durch die Zeilen in mehrere Gruppen unterteilt, verwendet sapply Spalte für jeden Unterdatenrahmens bedeuten, zu finden.

## implicit splitting 
do.call(rbind, by(dat, g, sapply, mean)) 

## explicit splitting 
do.call(rbind, lapply(split(dat, g), sapply, mean)) 

Wenn Sie eine Matrix mat anstatt einen Datenrahmen haben, können wir

apply(mat, 2L, tapply, INDEX = g, mean) 

und

do.call(rbind, by(mat, g, colMeans)) 

Testdaten in ähnlicher Weise tun

dat <- data.frame(V1 = 1:6, V2 = 7:12, V3 = 13:18) 

mat <- matrix(1:18, 6) 

g <- gl(3, 2, labels = letters[1:3]) 
+0

Große Lösung ..Für meine Zwecke ist die Antwort von @MarkPeterson relevanter, aber beide funktionieren. – c0ba1t

Verwandte Themen