2016-09-13 3 views
-1

Ausgehend von einer Tabelle von 372 Spalten und 12.000 Zeilen in R, muss ich eine neue Tabelle mit Spalten erstellen, die Zeilen mit der Summe der gleichen Zeile aus den Spalten 1: 4 enthalten , dann 5: 8, dann 9:12 und so weiter bis zur Spalte 372 der ursprünglichen Tabelle. Hier ein kurzes Beispiel:Summe der Werte von Gruppen von 4 zusammenhängenden Spalten in R

Eingang:

m = structure(c(3L, 1L, 2L, 6L, 3L, 1L, 1L, 8L, 1L, 5L, 2L, 1L, 3L, 7L, 
+ 1L, 1L), .Dim = c(2L, 8L), .Dimnames = list(c("r1", "r2"), c("a", "b", 
+"c", "d", "e", "f", "g", "h"))) 

die wie folgt aussieht:

a b c d e f g h 
r1 3 2 3 1 1 2 3 1 
r2 1 6 1 8 5 1 7 1 

Erwartete Ausgabe:

A B 
r1 9 7 
r2 16 14 

So, A = a + b + c + d, und B = e + f + g + h. Einfach mit einer kleinen Tabelle in Excel zu tun. Spalten a-d entsprechen einer Gruppe, e-f einer anderen, wenn das hilft.

+0

Sie wahrscheinlich 'dput' das Objekt benötigen, mit dieser reproduzierbar zu machen, wie hier beschrieben: http: //stackoverflow.com/a/28481250/ Andernfalls haben Sie möglicherweise ein Objekt mit einer Anzahl von verschiedenen Klassen (data.frame, matrix, table). Zum Beispiel könnten Sie 'm = Struktur (c (3L, 1L, 2L, 6L, 3L, 1L, 1L, 8L, 1L, 5L, 2L, 1L, 3L, 7L, 1L, 1L), .Dim = bearbeiten c (2L, 8L),.Dimnames = Liste (c ("r1", "r2"), c ("a", "b", "c", "d", "e", "f", "g", "h"))) in deine Frage, wenn du eine Matrix hast. – Frank

+0

Danke für den Hinweis Frank. Ich habe meine Frage bereits bearbeitet. – fibar

Antwort

3

Eine Basis R-Lösung an, dass df ist Ihr Datenrahmen:

cols = 8 
do.call(cbind, lapply(seq(1, ncols, 4), function(i) rowSums(df[i:(i+3)]))) 
# [,1] [,2] 
# r1 9 7 
# r2 16 14 
4

Die Frage ist zur Zeit underspecified, aber angenommen, Sie eine Matrix haben ...

m = structure(c(3L, 1L, 2L, 6L, 3L, 1L, 1L, 8L, 1L, 5L, 2L, 1L, 3L, 
7L, 1L, 1L), .Dim = c(2L, 8L), .Dimnames = list(c("r1", "r2"), 
    c("a", "b", "c", "d", "e", "f", "g", "h"))) 

Ihre Spaltenzuordnung Fabrikat:

map = data.frame(old = colnames(m), new = rep(LETTERS, each=4, length.out=ncol(m))) 

    old new 
1 a A 
2 b A 
3 c A 
4 d A 
5 e B 
6 f B 
7 g B 
8 h B 

Und dann rowsum von ihm:

res = rowsum(t(m), map$new) 

    r1 r2 
A 9 16 
B 7 14 

Wir haben die Daten mit t hier umzusetzen, da R rowsum aber keine colsum hat. Sie können es anschließend wieder transponieren, wie zB t(res).

+0

Wenn du wirklich Namen wie A, B, ... machst und 374 Spalten hast, wirst du natürlich ausgehen. In diesem Fall könnten Sie Buchstabenpaare verwenden (für 26^2 Kombinationen): Anstelle von 'LETTERS' in der Antwort schreiben Sie' do.call (paste0, expand.grid (LETTERS, LETTERS)) '' – Frank

+0

Danke Frank. Dies funktionierte, einschließlich des letzten Vorschlags für BRIEFE. Obwohl mein Objekt eine Liste ist. Sollten wir das in unserer Frage/Antwort ändern? – fibar

+0

@fibar Hm, ich bin mir nicht sicher, was du mit einer Liste meinst, aber ich würde sagen, mach weiter und füge es hinzu, wenn du denkst, dass es relevant ist. – Frank

0

Sie können dies auf vektorisierte Weise tun, wenn Sie Ihre ursprünglichen Daten in eine Matrix mit 4 Spalten transformieren, dann rowSums verwenden und sie dann so umwandeln, dass sie den Zeilen des ursprünglichen Datenrahmens entsprechen. Hier ist es in einem langen Befehl

df <- read.table(header = TRUE, text = "a b c d e f g h 
      3 2 3 1 1 2 3 1 
       1 6 1 8 5 1 7 1") 

    matrix(rowSums(matrix(as.vector(t(as.matrix(df))), 
     ncol = 4, byrow = TRUE)), ncol = ncol(df)/4, byrow = TRUE) 

    #  [,1] [,2] 
    #[1,] 9 7 
    #[2,] 16 14 

Bearbeiten: Um die Zeilennamen zu erhalten, wenn z. rownames(df) <- c("r1", "r2"), wenden Sie sie einfach auf die resultierende Matrix an (die Zeilenreihenfolge bleibt erhalten), dh führen Sie rownames(result) <- rownames(df) aus.

+0

Es wäre schön, die 'r1',' r2' Labels zu erhalten, denke ich. Nicht sicher, ob das hier passieren würde, da du sie von deiner Eingabe ausgeschlossen hast. – Frank

+1

@Frank Ich dachte, das waren nur Zeilennamen. Diese können am Ende wieder hinzugefügt werden, ich werde den Beitrag bearbeiten. – konvas

0

Ein anderer Weg:

df <- data.frame(t(matrix(colSums(matrix(t(df), nrow=4)),nrow=nrow(df)))) 
## X1 X2 
##1 9 7 
##2 16 14 
  1. zuerst die Daten zu einer 4 x (ncol(df)/4 * now(df)) transponierte Matrix wobei nun jede Spalte für jede Zeile in dem ursprünglichen Datenrahmen eine Gruppe von vier Spalten.
  2. Summe jeder Spalte colSums
  3. die Daten transponieren zurück zu einem Datenrahmen mit der ursprünglichen Anzahl der Zeilen
Verwandte Themen